bevy/crates/bevy_transform/src/components/transform.rs
Marek Legris 5acebed731
Transform and GlobalTransform are now Similarities (#596)
Transform and GlobalTransform are now Similarities.

This resolves precision errors and simplifies the api

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2020-10-18 13:03:16 -07:00

153 lines
3.7 KiB
Rust

use bevy_math::{Mat3, Mat4, Quat, Vec3};
use bevy_property::Properties;
use std::ops::Mul;
use super::GlobalTransform;
#[derive(Debug, PartialEq, Clone, Copy, Properties)]
pub struct Transform {
pub translation: Vec3,
pub rotation: Quat,
pub scale: Vec3,
}
impl Transform {
#[inline]
pub fn identity() -> Self {
Transform {
translation: Vec3::zero(),
rotation: Quat::identity(),
scale: Vec3::one(),
}
}
#[inline]
pub fn from_matrix(matrix: Mat4) -> Self {
let (scale, rotation, translation) = matrix.to_scale_rotation_translation();
Transform {
translation,
rotation,
scale,
}
}
#[inline]
pub fn from_translation(translation: Vec3) -> Self {
Transform {
translation,
..Default::default()
}
}
#[inline]
pub fn from_rotation(rotation: Quat) -> Self {
Transform {
rotation,
..Default::default()
}
}
#[inline]
pub fn from_scale(scale: Vec3) -> Self {
Transform {
scale,
..Default::default()
}
}
/// Returns transform with the same translation and scale, but rotation so that transform.forward() points at the origin
#[inline]
pub fn looking_at_origin(self) -> Self {
self.looking_at(Vec3::zero(), Vec3::unit_y())
}
/// Returns transform with the same translation and scale, but rotation so that transform.forward() points at target
#[inline]
pub fn looking_at(mut self, target: Vec3, up: Vec3) -> Self {
self.look_at(target, up);
self
}
#[inline]
pub fn compute_matrix(&self) -> Mat4 {
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
}
#[inline]
pub fn forward(&self) -> Vec3 {
self.rotation * Vec3::unit_z()
}
#[inline]
/// Rotate the transform by the given rotation
pub fn rotate(&mut self, rotation: Quat) {
self.rotation *= rotation;
}
#[inline]
pub fn mul_transform(&self, transform: Transform) -> Self {
let translation = self.mul_vec3(transform.translation);
let rotation = self.rotation * transform.rotation;
let scale = self.scale * transform.scale;
Transform {
scale,
rotation,
translation,
}
}
#[inline]
pub fn mul_vec3(&self, mut value: Vec3) -> Vec3 {
value = self.rotation * value;
value = self.scale * value;
value += self.translation;
value
}
#[inline]
pub fn apply_non_uniform_scale(&mut self, scale: Vec3) {
self.scale *= scale;
}
#[inline]
pub fn look_at(&mut self, target: Vec3, up: Vec3) {
let forward = Vec3::normalize(self.translation - target);
let right = up.cross(forward).normalize();
let up = forward.cross(right);
self.rotation = Quat::from_rotation_mat3(&Mat3::from_cols(right, up, forward));
}
}
impl Default for Transform {
fn default() -> Self {
Self::identity()
}
}
impl From<GlobalTransform> for Transform {
fn from(transform: GlobalTransform) -> Self {
Self {
translation: transform.translation,
rotation: transform.rotation,
scale: transform.scale,
}
}
}
impl Mul<Transform> for Transform {
type Output = Transform;
fn mul(self, transform: Transform) -> Self::Output {
self.mul_transform(transform)
}
}
impl Mul<Vec3> for Transform {
type Output = Vec3;
fn mul(self, value: Vec3) -> Self::Output {
self.mul_vec3(value)
}
}