1use glam::{Mat4, Quat, Vec3};
4
5#[derive(Clone, Copy, Debug)]
6pub struct Transform {
7 pub position: Vec3,
8 pub rotation: Quat,
9 pub scale: Vec3,
10}
11
12impl Default for Transform {
13 fn default() -> Self {
14 Self {
15 position: Vec3::ZERO,
16 rotation: Quat::IDENTITY,
17 scale: Vec3::ONE,
18 }
19 }
20}
21
22impl Transform {
23 pub fn new() -> Self {
24 Self::default()
25 }
26
27 pub fn from_position(position: Vec3) -> Self {
28 Self {
29 position,
30 ..Default::default()
31 }
32 }
33
34 pub fn look_at(&mut self, target: Vec3, up: Vec3) {
35 let forward = (target - self.position).normalize_or_zero();
36 if forward != Vec3::ZERO {
37 let right = up.cross(forward).normalize_or_zero();
39 let new_up = forward.cross(right).normalize_or_zero();
40
41 if right != Vec3::ZERO && new_up != Vec3::ZERO {
42 let m = glam::Mat3::from_cols(right, new_up, forward);
43 self.rotation = Quat::from_mat3(&m);
44 } else {
45 self.rotation = Quat::from_rotation_arc(Vec3::NEG_Z, forward);
47 }
48 }
49 }
50
51 pub fn forward(&self) -> Vec3 {
52 self.rotation * Vec3::NEG_Z
53 }
54
55 pub fn right(&self) -> Vec3 {
56 self.rotation * Vec3::X
57 }
58
59 pub fn up(&self) -> Vec3 {
60 self.rotation * Vec3::Y
61 }
62
63 pub fn to_matrix(&self) -> Mat4 {
64 Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.position)
65 }
66}