151 lines
3.9 KiB
Rust
151 lines
3.9 KiB
Rust
use bevy_math::{Mat3, Mat4, Quat, Vec3, Vec4};
|
|
use bevy_property::Properties;
|
|
use std::fmt;
|
|
|
|
#[derive(Debug, PartialEq, Clone, Copy, Properties)]
|
|
pub struct Transform {
|
|
value: Mat4,
|
|
}
|
|
|
|
impl Transform {
|
|
#[inline(always)]
|
|
pub fn new(value: Mat4) -> Self {
|
|
Transform { value }
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub fn identity() -> Self {
|
|
Transform {
|
|
value: Mat4::identity(),
|
|
}
|
|
}
|
|
|
|
pub fn from_translation(translation: Vec3) -> Self {
|
|
Transform::new(Mat4::from_translation(translation))
|
|
}
|
|
|
|
pub fn from_rotation(rotation: Quat) -> Self {
|
|
Transform::new(Mat4::from_quat(rotation))
|
|
}
|
|
|
|
pub fn from_scale(scale: f32) -> Self {
|
|
Transform::new(Mat4::from_scale(Vec3::splat(scale)))
|
|
}
|
|
|
|
pub fn from_translation_rotation_scale(translation: Vec3, rotation: Quat, scale: f32) -> Self {
|
|
Transform::new(Mat4::from_scale_rotation_translation(
|
|
Vec3::splat(scale),
|
|
rotation,
|
|
translation,
|
|
))
|
|
}
|
|
|
|
pub fn from_non_uniform_scale(scale: Vec3) -> Self {
|
|
Transform::new(Mat4::from_scale(scale))
|
|
}
|
|
|
|
pub fn with_translation(mut self, translation: Vec3) -> Self {
|
|
self.translate(translation);
|
|
self
|
|
}
|
|
|
|
pub fn with_rotation(mut self, rotation: Quat) -> Self {
|
|
self.rotate(rotation);
|
|
self
|
|
}
|
|
|
|
pub fn with_scale(mut self, scale: f32) -> Self {
|
|
self.apply_scale(scale);
|
|
self
|
|
}
|
|
|
|
pub fn with_non_uniform_scale(mut self, scale: Vec3) -> Self {
|
|
self.apply_non_uniform_scale(scale);
|
|
self
|
|
}
|
|
|
|
pub fn value(&self) -> &Mat4 {
|
|
&self.value
|
|
}
|
|
|
|
pub fn value_mut(&mut self) -> &mut Mat4 {
|
|
&mut self.value
|
|
}
|
|
|
|
pub fn translation(&self) -> Vec3 {
|
|
Vec3::from(self.value.w_axis().truncate())
|
|
}
|
|
|
|
pub fn translation_mut(&mut self) -> &mut Vec4 {
|
|
self.value.w_axis_mut()
|
|
}
|
|
|
|
pub fn rotation(&self) -> Quat {
|
|
let scale = self.scale();
|
|
|
|
Quat::from_rotation_mat3(&Mat3::from_cols(
|
|
Vec3::from(self.value.x_axis().truncate()) / scale.x(),
|
|
Vec3::from(self.value.y_axis().truncate()) / scale.y(),
|
|
Vec3::from(self.value.z_axis().truncate()) / scale.z(),
|
|
))
|
|
}
|
|
|
|
pub fn scale(&self) -> Vec3 {
|
|
Vec3::new(
|
|
self.value.x_axis().truncate().length(),
|
|
self.value.y_axis().truncate().length(),
|
|
self.value.z_axis().truncate().length(),
|
|
)
|
|
}
|
|
|
|
pub fn set_translation(&mut self, translation: Vec3) {
|
|
*self.value.w_axis_mut() = translation.extend(1.0);
|
|
}
|
|
|
|
pub fn set_rotation(&mut self, rotation: Quat) {
|
|
self.value =
|
|
Mat4::from_scale_rotation_translation(self.scale(), rotation, self.translation());
|
|
}
|
|
|
|
pub fn set_scale(&mut self, scale: f32) {
|
|
self.value = Mat4::from_scale_rotation_translation(
|
|
Vec3::splat(scale),
|
|
self.rotation(),
|
|
self.translation(),
|
|
);
|
|
}
|
|
|
|
pub fn set_non_uniform_scale(&mut self, scale: Vec3) {
|
|
self.value =
|
|
Mat4::from_scale_rotation_translation(scale, self.rotation(), self.translation());
|
|
}
|
|
|
|
pub fn translate(&mut self, translation: Vec3) {
|
|
*self.value.w_axis_mut() += translation.extend(0.0);
|
|
}
|
|
|
|
pub fn rotate(&mut self, rotation: Quat) {
|
|
self.value = Mat4::from_quat(rotation) * self.value;
|
|
}
|
|
|
|
pub fn apply_scale(&mut self, scale: f32) {
|
|
self.value = Mat4::from_scale(Vec3::splat(scale)) * self.value;
|
|
}
|
|
|
|
pub fn apply_non_uniform_scale(&mut self, scale: Vec3) {
|
|
self.value = Mat4::from_scale(scale) * self.value;
|
|
}
|
|
}
|
|
|
|
impl Default for Transform {
|
|
fn default() -> Self {
|
|
Self::identity()
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Transform {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(f, "{}", self.value)
|
|
}
|
|
}
|