use bevy::prelude::*;
#[derive(Component, Debug, PartialEq, Clone, Copy, Reflect, FromReflect)]
#[reflect(Component, PartialEq, Default)]
pub struct Transform2d {
pub translation: Vec2,
pub rotation: f32,
pub scale: Vec2,
pub z_translation: f32,
}
impl Default for Transform2d {
fn default() -> Self {
Transform2d::IDENTITY
}
}
impl Transform2d {
#[inline]
pub fn from_xy(x: f32, y: f32) -> Self {
Transform2d::from_translation(Vec2::new(x, y))
}
pub const IDENTITY: Self = Transform2d {
translation: Vec2::ZERO,
rotation: 0.,
scale: Vec2::ONE,
z_translation: 0.,
};
#[inline]
pub fn from_translation(translation: Vec2) -> Self {
Transform2d {
translation,
..Self::IDENTITY
}
}
#[inline]
pub fn from_rotation(rotation: f32) -> Self {
Transform2d {
rotation,
..Self::IDENTITY
}
}
#[inline]
pub fn from_scale(scale: impl IntoScale) -> Self {
Transform2d {
scale: scale.into_scale(),
..Self::IDENTITY
}
}
#[must_use]
#[inline]
pub fn with_translation(mut self, translation: Vec2) -> Self {
self.translation = translation;
self
}
#[must_use]
#[inline]
pub fn with_rotation(mut self, rotation: f32) -> Self {
self.rotation = rotation;
self
}
#[must_use]
#[inline]
pub fn with_scale(mut self, scale: impl IntoScale) -> Self {
self.scale = scale.into_scale();
self
}
#[must_use]
#[inline]
pub fn with_z_translation(mut self, z_translation: f32) -> Self {
self.z_translation = z_translation;
self
}
#[inline]
pub fn local_x(&self) -> Vec2 {
self.rotation_matrix() * Vec2::X
}
#[inline]
pub fn left(&self) -> Vec2 {
-self.local_x()
}
#[inline]
pub fn right(&self) -> Vec2 {
self.local_x()
}
#[inline]
pub fn local_y(&self) -> Vec2 {
self.rotation_matrix() * Vec2::Y
}
#[inline]
pub fn up(&self) -> Vec2 {
self.local_y()
}
#[inline]
pub fn down(&self) -> Vec2 {
-self.local_y()
}
#[inline]
pub fn rotation_matrix(&self) -> Mat2 {
Mat2::from_angle(self.rotation)
}
#[inline]
pub fn translate_around(&mut self, point: Vec2, angle: f32) {
self.translation = point + Mat2::from_angle(angle) * (self.translation - point);
}
#[inline]
pub fn rotate_around(&mut self, point: Vec2, angle: f32) {
self.translate_around(point, angle);
self.rotation += angle;
}
}
impl From<Transform2d> for Transform {
#[inline]
fn from(transform2d: Transform2d) -> Self {
Transform {
translation: transform2d.translation.extend(transform2d.z_translation),
rotation: Quat::from_rotation_z(transform2d.rotation),
scale: transform2d.scale.extend(1.),
}
}
}
impl From<Transform> for Transform2d {
fn from(transform_3d: Transform) -> Self {
Transform2d {
translation: transform_3d.translation.truncate(),
rotation: transform_3d.rotation.to_euler(EulerRot::ZYX).0,
scale: transform_3d.scale.truncate(),
z_translation: transform_3d.translation.z,
}
}
}
pub trait IntoScale {
fn into_scale(self) -> Vec2;
}
impl IntoScale for Vec2 {
fn into_scale(self) -> Vec2 {
self
}
}
impl IntoScale for f32 {
fn into_scale(self) -> Vec2 {
Vec2::splat(self)
}
}