resonance 0.1.0

A modular game engine. Heavy work in progress.
Documentation

use bevy_ecs::prelude::*;
use crate::core::math::*;
use serde::{Deserialize, Serialize};

#[derive(Component, Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Transform {
    pub position: Vec3,
    pub rotation: Quat,
    pub scale: Vec3,
}

impl Transform {

    pub fn new() -> Self {
        Self::default()
    }

    pub fn from_position(position: Vec3) -> Self {
        Self {
            position,
            ..Default::default()
        }
    }

    pub fn from_rotation(rotation: Quat) -> Self {
        Self {
            rotation,
            ..Default::default()
        }
    }

    pub fn from_scale(scale: Vec3) -> Self {
        Self {
            scale,
            ..Default::default()
        }
    }

    pub fn from_prs(position: Vec3, rotation: Quat, scale: Vec3) -> Self {
        Self {
            position,
            rotation,
            scale,
        }
    }

    pub fn translate(&mut self, translation: Vec3) {
        self.position += translation;
    }

    pub fn rotate(&mut self, rotation: Quat) {
        self.rotation = rotation * self.rotation;
    }

    pub fn rotate_axis(&mut self, axis: Vec3, angle: f32) {
        self.rotate(Quat::from_axis_angle(axis, angle));
    }

    pub fn rotate_x(&mut self, angle: f32) {
        self.rotate_axis(Vec3::X, angle);
    }

    pub fn rotate_y(&mut self, angle: f32) {
        self.rotate_axis(Vec3::Y, angle);
    }

    pub fn rotate_z(&mut self, angle: f32) {
        self.rotate_axis(Vec3::Z, angle);
    }

    pub fn forward(&self) -> Vec3 {
        self.rotation * -Vec3::Z
    }

    pub fn right(&self) -> Vec3 {
        self.rotation * Vec3::X
    }

    pub fn up(&self) -> Vec3 {
        self.rotation * Vec3::Y
    }

    pub fn compute_matrix(&self) -> Mat4 {
        Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.position)
    }

    pub fn look_at(&mut self, target: Vec3, up: Vec3) {

        let view_matrix = Mat4::look_at_rh(self.position, target, up);

        let transform_matrix = view_matrix.inverse();
        self.rotation = Quat::from_mat4(&transform_matrix);
    }
}

impl Default for Transform {
    fn default() -> Self {
        Self {
            position: Vec3::ZERO,
            rotation: Quat::IDENTITY,
            scale: Vec3::ONE,
        }
    }
}

#[derive(Component, Debug, Clone, Copy)]
pub struct GlobalTransform {

    matrix: Mat4,
}

impl GlobalTransform {

    pub fn from_matrix(matrix: Mat4) -> Self {
        Self { matrix }
    }

    pub fn from_transform(transform: &Transform) -> Self {
        Self {
            matrix: transform.compute_matrix(),
        }
    }

    pub fn matrix(&self) -> Mat4 {
        self.matrix
    }

    pub fn position(&self) -> Vec3 {
        self.matrix.w_axis.truncate()
    }

    pub fn rotation(&self) -> Quat {
        Quat::from_mat4(&self.matrix)
    }

    pub fn scale(&self) -> Vec3 {
        Vec3::new(
            self.matrix.x_axis.truncate().length(),
            self.matrix.y_axis.truncate().length(),
            self.matrix.z_axis.truncate().length(),
        )
    }

    pub fn from_transform_and_parent(transform: &Transform, parent: &GlobalTransform) -> Self {
        Self {
            matrix: parent.matrix * transform.compute_matrix(),
        }
    }
}

impl Default for GlobalTransform {
    fn default() -> Self {
        Self {
            matrix: Mat4::IDENTITY,
        }
    }
}