use crate::ecs::Component;
pub use cgmath::{Deg, EuclideanSpace, Matrix4, Point3, Rad, SquareMatrix, Vector3, perspective};
#[derive(Debug, Clone)]
pub struct Transform {
pub position: Vector3<f32>,
pub rotation: Vector3<f32>, pub scale: Vector3<f32>,
}
impl Component for Transform {}
impl Default for Transform {
fn default() -> Self {
Self {
position: Vector3::new(0.0, 0.0, 0.0),
rotation: Vector3::new(0.0, 0.0, 0.0),
scale: Vector3::new(1.0, 1.0, 1.0),
}
}
}
impl Transform {
pub fn at_position(position: Vector3<f32>) -> Self {
Self {
position,
..Default::default()
}
}
pub fn with_rotation_deg(rotation: Vector3<f32>) -> Self {
Self {
rotation: Vector3::new(
rotation.x.to_radians(),
rotation.y.to_radians(),
rotation.z.to_radians(),
),
..Default::default()
}
}
pub fn with_scale(scale: Vector3<f32>) -> Self {
Self {
scale,
..Default::default()
}
}
pub fn set_position(&mut self, position: Vector3<f32>) {
self.position = position;
}
pub fn set_rotation_deg(&mut self, rotation: Vector3<f32>) {
self.rotation = Vector3::new(
rotation.x.to_radians(),
rotation.y.to_radians(),
rotation.z.to_radians(),
);
}
pub fn set_rotation_rad(&mut self, rotation: Vector3<f32>) {
self.rotation = rotation;
}
pub fn set_scale(&mut self, scale: Vector3<f32>) {
self.scale = scale;
}
pub fn matrix(&self) -> Matrix4<f32> {
Matrix4::from_translation(self.position)
* Matrix4::from_angle_y(Rad(self.rotation.y))
* Matrix4::from_angle_x(Rad(self.rotation.x))
* Matrix4::from_angle_z(Rad(self.rotation.z))
* Matrix4::from_nonuniform_scale(self.scale.x, self.scale.y, self.scale.z)
}
pub fn rotation_deg(&self) -> Vector3<f32> {
Vector3::new(
self.rotation.x.to_degrees(),
self.rotation.y.to_degrees(),
self.rotation.z.to_degrees(),
)
}
}
#[derive(Debug, Clone)]
pub struct Velocity {
pub linear: Vector3<f32>,
pub angular: Vector3<f32>, }
impl Component for Velocity {}
impl Default for Velocity {
fn default() -> Self {
Self {
linear: Vector3::new(0.0, 0.0, 0.0),
angular: Vector3::new(0.0, 0.0, 0.0),
}
}
}
impl Velocity {
pub fn linear(linear: Vector3<f32>) -> Self {
Self {
linear,
..Default::default()
}
}
pub fn angular(angular: Vector3<f32>) -> Self {
Self {
angular,
..Default::default()
}
}
}
pub mod utils {
use super::*;
pub fn look_at(eye: Point3<f32>, target: Point3<f32>, up: Vector3<f32>) -> Matrix4<f32> {
Matrix4::look_at_rh(eye, target, up)
}
pub fn perspective_matrix(fov_deg: f32, aspect: f32, near: f32, far: f32) -> Matrix4<f32> {
perspective(Deg(fov_deg), aspect, near, far)
}
pub fn lerp(a: Vector3<f32>, b: Vector3<f32>, t: f32) -> Vector3<f32> {
a + (b - a) * t
}
pub fn slerp_euler(a: Vector3<f32>, b: Vector3<f32>, t: f32) -> Vector3<f32> {
lerp(a, b, t)
}
}