use elicitation::{elicit_newtype, elicit_newtype_traits};
use elicitation_derive::reflect_methods;
use std::sync::Arc;
elicit_newtype!(bevy::transform::components::Transform, as Transform);
elicit_newtype_traits!(Transform, bevy::transform::components::Transform, [eq]);
impl serde::Serialize for Transform {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
(*self.0).serialize(s)
}
}
impl<'de> serde::Deserialize<'de> for Transform {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
bevy::transform::components::Transform::deserialize(d).map(|v| Transform(Arc::new(v)))
}
}
impl From<Transform> for bevy::transform::components::Transform {
fn from(v: Transform) -> Self {
*v.0
}
}
#[reflect_methods]
impl Transform {
#[tracing::instrument(skip(self))]
pub fn transform_translation(&self) -> [f32; 3] {
[
self.0.translation.x,
self.0.translation.y,
self.0.translation.z,
]
}
#[tracing::instrument(skip(self))]
pub fn translation_x(&self) -> f32 {
self.0.translation.x
}
#[tracing::instrument(skip(self))]
pub fn translation_y(&self) -> f32 {
self.0.translation.y
}
#[tracing::instrument(skip(self))]
pub fn translation_z(&self) -> f32 {
self.0.translation.z
}
#[tracing::instrument(skip(self))]
pub fn rotation(&self) -> [f32; 4] {
[
self.0.rotation.x,
self.0.rotation.y,
self.0.rotation.z,
self.0.rotation.w,
]
}
#[tracing::instrument(skip(self))]
pub fn scale(&self) -> [f32; 3] {
[self.0.scale.x, self.0.scale.y, self.0.scale.z]
}
#[tracing::instrument(skip(self))]
pub fn identity(&self) -> Transform {
Transform::from(bevy::transform::components::Transform::IDENTITY)
}
#[tracing::instrument(skip(self))]
pub fn from_xyz_constructor(&self, x: f32, y: f32, z: f32) -> Transform {
Transform::from(bevy::transform::components::Transform::from_xyz(x, y, z))
}
#[tracing::instrument(skip(self))]
pub fn from_scale_constructor(&self, scale: f32) -> Transform {
Transform::from(bevy::transform::components::Transform::from_scale(
bevy::math::Vec3::splat(scale),
))
}
#[tracing::instrument(skip(self))]
pub fn right(&self) -> [f32; 3] {
let v = self.0.right();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn left(&self) -> [f32; 3] {
let v = self.0.left();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn up(&self) -> [f32; 3] {
let v = self.0.up();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn down(&self) -> [f32; 3] {
let v = self.0.down();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn forward(&self) -> [f32; 3] {
let v = self.0.forward();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn back(&self) -> [f32; 3] {
let v = self.0.back();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn with_translation(&self, x: f32, y: f32, z: f32) -> Transform {
Transform::from((*self.0).with_translation(bevy::math::Vec3::new(x, y, z)))
}
#[tracing::instrument(skip(self))]
pub fn with_rotation(&self, x: f32, y: f32, z: f32, w: f32) -> Transform {
Transform::from((*self.0).with_rotation(bevy::math::Quat::from_xyzw(x, y, z, w)))
}
#[tracing::instrument(skip(self))]
pub fn with_scale(&self, x: f32, y: f32, z: f32) -> Transform {
Transform::from((*self.0).with_scale(bevy::math::Vec3::new(x, y, z)))
}
#[tracing::instrument(skip(self))]
pub fn rotate_x(&self, angle: f32) -> Transform {
let mut t = *self.0;
t.rotate_x(angle);
Transform::from(t)
}
#[tracing::instrument(skip(self))]
pub fn rotate_y(&self, angle: f32) -> Transform {
let mut t = *self.0;
t.rotate_y(angle);
Transform::from(t)
}
#[tracing::instrument(skip(self))]
pub fn rotate_z(&self, angle: f32) -> Transform {
let mut t = *self.0;
t.rotate_z(angle);
Transform::from(t)
}
#[tracing::instrument(skip(self))]
pub fn rotate_local_x(&self, angle: f32) -> Transform {
let mut t = *self.0;
t.rotate_local_x(angle);
Transform::from(t)
}
#[tracing::instrument(skip(self))]
pub fn rotate_local_y(&self, angle: f32) -> Transform {
let mut t = *self.0;
t.rotate_local_y(angle);
Transform::from(t)
}
#[tracing::instrument(skip(self))]
pub fn rotate_local_z(&self, angle: f32) -> Transform {
let mut t = *self.0;
t.rotate_local_z(angle);
Transform::from(t)
}
#[tracing::instrument(skip(self))]
pub fn mul_transform(&self, other: Transform) -> Transform {
Transform::from(self.0.mul_transform(*other.0))
}
#[tracing::instrument(skip(self))]
pub fn transform_point(&self, x: f32, y: f32, z: f32) -> [f32; 3] {
let p = self.0.transform_point(bevy::math::Vec3::new(x, y, z));
[p.x, p.y, p.z]
}
#[tracing::instrument(skip(self))]
pub fn is_finite(&self) -> bool {
self.0.is_finite()
}
#[tracing::instrument(skip(self))]
pub fn compute_matrix(&self) -> [[f32; 4]; 4] {
let m = self.0.to_matrix();
m.to_cols_array_2d()
}
}
mod emit_impls_transform {
use super::Transform;
use elicitation::emit_code::ToCodeLiteral;
use proc_macro2::TokenStream;
impl ToCodeLiteral for Transform {
fn to_code_literal(&self) -> TokenStream {
let [tx, ty, tz] = [
self.0.translation.x,
self.0.translation.y,
self.0.translation.z,
];
let [rx, ry, rz, rw] = [
self.0.rotation.x,
self.0.rotation.y,
self.0.rotation.z,
self.0.rotation.w,
];
let [sx, sy, sz] = [self.0.scale.x, self.0.scale.y, self.0.scale.z];
quote::quote! {
::bevy::transform::components::Transform {
translation: ::bevy::math::Vec3::new(#tx, #ty, #tz),
rotation: ::bevy::math::Quat::from_xyzw(#rx, #ry, #rz, #rw),
scale: ::bevy::math::Vec3::new(#sx, #sy, #sz),
}
}
}
}
}
impl elicitation::ElicitComplete for Transform {}
elicit_newtype!(bevy::transform::components::GlobalTransform, as GlobalTransform);
elicit_newtype_traits!(
GlobalTransform,
bevy::transform::components::GlobalTransform,
[]
);
impl serde::Serialize for GlobalTransform {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeSeq;
let cols = self.0.affine().to_cols_array();
let mut seq = s.serialize_seq(Some(cols.len()))?;
for c in &cols {
seq.serialize_element(c)?;
}
seq.end()
}
}
impl<'de> serde::Deserialize<'de> for GlobalTransform {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let cols: Vec<f32> = serde::Deserialize::deserialize(d)?;
if cols.len() != 12 {
return Err(serde::de::Error::custom("expected 12 f32 values"));
}
let arr: [f32; 12] = cols.try_into().unwrap();
let affine = bevy::math::Affine3A::from_cols_array(&arr);
Ok(GlobalTransform(Arc::new(
bevy::transform::components::GlobalTransform::from(affine),
)))
}
}
impl From<GlobalTransform> for bevy::transform::components::GlobalTransform {
fn from(v: GlobalTransform) -> Self {
Arc::try_unwrap(v.0).unwrap_or_else(|arc| *arc)
}
}
#[reflect_methods]
impl GlobalTransform {
#[tracing::instrument(skip(self))]
pub fn global_transform_translation(&self) -> [f32; 3] {
let t = self.0.translation();
[t.x, t.y, t.z]
}
#[tracing::instrument(skip(self))]
pub fn compute_transform(&self) -> Transform {
Transform::from(self.0.compute_transform())
}
#[tracing::instrument(skip(self))]
pub fn global_forward(&self) -> [f32; 3] {
let v = self.0.forward();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn global_back(&self) -> [f32; 3] {
let v = self.0.back();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn global_up(&self) -> [f32; 3] {
let v = self.0.up();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn global_down(&self) -> [f32; 3] {
let v = self.0.down();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn global_right(&self) -> [f32; 3] {
let v = self.0.right();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn global_left(&self) -> [f32; 3] {
let v = self.0.left();
[v.x, v.y, v.z]
}
#[tracing::instrument(skip(self))]
pub fn global_transform_point(&self, x: f32, y: f32, z: f32) -> [f32; 3] {
let p = self.0.transform_point(bevy::math::Vec3::new(x, y, z));
[p.x, p.y, p.z]
}
#[tracing::instrument(skip(self))]
pub fn matrix_cols(&self) -> [[f32; 4]; 4] {
self.0.to_matrix().to_cols_array_2d()
}
}
mod emit_impls_global {
use super::GlobalTransform;
use elicitation::emit_code::ToCodeLiteral;
use proc_macro2::TokenStream;
impl ToCodeLiteral for GlobalTransform {
fn to_code_literal(&self) -> TokenStream {
let cols = self.0.affine().to_cols_array();
quote::quote! {
::bevy::transform::components::GlobalTransform::from(
::bevy::math::Affine3A::from_cols_array(&[#(#cols),*])
)
}
}
}
}
impl elicitation::ElicitComplete for GlobalTransform {}