implement simple ecs systems

This commit is contained in:
SeanOMik 2023-06-29 01:17:30 -04:00
parent 6a30a17f5f
commit 1ef664165d
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
6 changed files with 50 additions and 180 deletions

View File

@ -11,7 +11,7 @@ pub struct CameraComponent {
impl Default for CameraComponent {
fn default() -> Self {
Self {
transform: Transform::new(),
transform: Transform::default(),
fov: Angle::Degrees(45.0),
mode: CameraProjectionMode::Perspective,
}

View File

@ -69,19 +69,6 @@ impl TickCounter {
}
}
struct JiggleEntitiesSystem {
}
impl SimpleSystem for JiggleEntitiesSystem {
fn execute_mut(&mut self, world: &mut World) -> anyhow::Result<()> {
for (_eid, (transform, )) in world.query_mut::<(&mut TransformComponent,)>() {
transform.transform.translate_vec3(glam::Vec3::new(0.0, 0.001, 0.0));
}
Ok(())
}
}
struct GameLoop {
window: Arc<Window>,
@ -96,9 +83,6 @@ struct GameLoop {
impl GameLoop {
pub async fn new(window: Arc<Window>, world: Arc<Mutex<World>>, user_systems: Vec<Box<dyn SimpleSystem>>) -> GameLoop {
/* let mut graph_exec = SystemGraphExecutor::new();
graph_exec.add_system("jiggle_entities".to_string(), Box::new(JiggleEntitiesSystem {}), &[]); */
Self {
window: Arc::clone(&window),
renderer: Box::new(BasicRenderer::create_with_window(window).await),

View File

@ -10,6 +10,7 @@ use ecs::components::mesh::MeshComponent;
use ecs::components::transform::TransformComponent;
use game::Game;
use hecs::World;
use tracing::debug;
use crate::ecs::SystemFnExecutor;
use crate::render::material::Material;
@ -78,11 +79,11 @@ async fn main() {
shader_id: 0,
texture: diffuse_texture
}),
TransformComponent::from(Transform::from_translation(0.005, 0.0, 0.0)),
TransformComponent::from(Transform::from_xyz(0.005, 0.0, 0.0)),
));
let mut camera = CameraComponent::new();
camera.transform.translate_vec3(glam::Vec3::new(0.0, 0.0, 2.0));
camera.transform.translation += glam::Vec3::new(0.0, 0.0, 2.0);
//camera.transform.rotate_y(Angle::Degrees(-25.0));
camera.transform.rotate_z(Angle::Degrees(-90.0));
world.spawn((camera,));
@ -90,7 +91,11 @@ async fn main() {
let jiggle_system = |world: &mut World| -> anyhow::Result<()> {
for (_eid, (transform, )) in world.query_mut::<(&mut TransformComponent,)>() {
let t = &mut transform.transform;
t.translate_vec3(glam::Vec3::new(t.x() * -1.0, 0.001, 0.0));
debug!("Translation: {}", t.translation);
t.translation += glam::Vec3::new(0.0, 0.001, 0.0);
t.translation.x *= -1.0
}
Ok(())

View File

@ -3,186 +3,75 @@ use glam::{Vec3, Mat4, Quat};
use crate::math::angle::{self, Angle};
#[repr(C)]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
#[derive(Debug, Copy, Clone)]
pub struct Transform {
matrix: glam::Mat4,
pub translation: Vec3,
pub rotation: Quat,
pub scale: Vec3,
}
impl Default for Transform {
fn default() -> Self {
Self {
matrix: glam::Mat4::IDENTITY
translation: Vec3::new(0.0, 0.0, 0.0),
rotation: Quat::IDENTITY,
scale: Vec3::new(1.0, 1.0, 1.0),
}
}
}
impl Into<glam::Mat4> for Transform {
/* impl Into<glam::Mat4> for Transform {
fn into(self) -> glam::Mat4 {
self.matrix
}
}
} */
// TODO: https://www.brainvoyager.com/bv/doc/UsersGuide/CoordsAndTransforms/SpatialTransformationMatrices.html
const ZERO_V3: Vec3 = Vec3::new(0.0, 0.0, 0.0);
const ONE_V3: Vec3 = Vec3::new(1.0, 1.0, 1.0);
#[allow(dead_code)]
impl Transform {
pub fn new() -> Self {
Self::default()
}
pub fn from_matrix(matrix: glam::Mat4) -> Self {
pub fn new(translation: Vec3, rotation: Quat, scale: Vec3) -> Self {
Self {
matrix,
translation,
rotation,
scale,
}
}
pub fn matrix(&self) -> glam::Mat4 {
self.matrix
pub fn from_translation(translation: Vec3) -> Self {
Self::new(translation, Quat::IDENTITY, ONE_V3)
}
/// Create Transform from scale, rotation (in degrees), and translation
pub fn from_scale_rotation_deg_translation(scale: Vec3, mut rotation: Vec3, translation: Vec3) -> Self {
rotation.x = angle::degrees_to_radians(rotation.x);
rotation.y = angle::degrees_to_radians(rotation.y);
rotation.z = angle::degrees_to_radians(rotation.z);
let rotation_quat = glam::Quat::from_euler(glam::EulerRot::XYZ, rotation.x, rotation.y, rotation.z);
let matrix = glam::Mat4::from_scale_rotation_translation(scale, rotation_quat, translation);
Self::from_matrix(matrix)
pub fn from_xyz(x: f32, y: f32, z: f32) -> Self {
Self::new(Vec3::new(x, y, z), Quat::IDENTITY, ONE_V3)
}
/// Create Transform from scale, rotation (in radians), and translation
pub fn from_scale_rotation_rad_translation(scale: Vec3, rotation: Vec3, translation: Vec3) -> Self {
let rotation_quat = glam::Quat::from_euler(glam::EulerRot::XYZ, rotation.x, rotation.y, rotation.z);
let matrix = glam::Mat4::from_scale_rotation_translation(scale, rotation_quat, translation);
Self::from_matrix(matrix)
pub fn calculate_mat4(&self) -> Mat4 {
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
}
/// Create Transform from scale, rotation (as a quaternion), and translation
pub fn from_scale_rotation_quat_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self {
let matrix = glam::Mat4::from_scale_rotation_translation(scale, rotation, translation);
Self::from_matrix(matrix)
/// Get the forward vector of the Transform.
pub fn forward(&self) -> Vec3 {
self.rotation * ONE_V3
}
pub fn from_translation_vec(translation: Vec3) -> Self {
let matrix = glam::Mat4::from_scale_rotation_translation(Vec3::new(1.0, 1.0, 1.0), Quat::IDENTITY, translation);
Self::from_matrix(matrix)
/// Rotate this transform using a Quaternion
pub fn rotate(&mut self, rotation: Quat) {
self.rotation = rotation * self.rotation;
}
pub fn from_translation(x: f32, y: f32, z: f32) -> Self {
Self::from_translation_vec(Vec3::new(x, y, z))
pub fn rotate_x(&mut self, angle: Angle) {
self.rotate(Quat::from_rotation_x(angle.to_radians()))
}
pub fn translate_vec3(&mut self, vec: Vec3) -> &mut Self {
let translation = glam::Mat4::from_translation(vec);
self.matrix *= translation;
self
pub fn rotate_y(&mut self, angle: Angle) {
self.rotate(Quat::from_rotation_y(angle.to_radians()))
}
/// Rotate around the given axis.
pub fn rotate_axis(&mut self, axis: Vec3, angle: Angle) -> &mut Self {
let radians = angle.to_radians();
let rotation = glam::Mat4::from_axis_angle(axis, radians);
self.matrix *= rotation;
self
}
// Rotate the transform with degrees
pub fn rotate_degrees(&mut self, mut x: f32, mut y: f32, mut z: f32) -> &mut Self {
// Convert degrees to radians
x = angle::degrees_to_radians(x);
y = angle::degrees_to_radians(y);
z = angle::degrees_to_radians(z);
let rotation = glam::Mat4::from_euler(glam::EulerRot::XYZ, x, y, z);
self.matrix *= rotation;
self
}
// Rotate the transform with degrees in a vec
pub fn rotate_degrees_vec(&mut self, mut rotation: Vec3) -> &mut Self {
self.rotate_degrees(rotation.x, rotation.y, rotation.z)
}
// Rotate the transform with radians
pub fn rotate_radians(&mut self, rotation: Vec3) -> &mut Self {
let rotation = glam::Mat4::from_euler(glam::EulerRot::XYZ, rotation.x, rotation.y, rotation.z);
self.matrix *= rotation;
self
}
/// Rotate the transform with a quaternion
pub fn rotate_quat(&mut self, quat: glam::Quat) -> &mut Self {
let rotation = glam::Mat4::from_quat(quat);
self.matrix *= rotation;
self
}
/// Rotate around the x axis.
pub fn rotate_x(&mut self, angle: Angle) -> &mut Self {
self.rotate_axis(Vec3::new(1.0, 0.0, 0.0), angle)
}
/// Rotate around the y axis.
pub fn rotate_y(&mut self, angle: Angle) -> &mut Self {
self.rotate_axis(Vec3::new(0.0, 1.0, 0.0), angle)
}
/// Rotate around the z axis.
pub fn rotate_z(&mut self, angle: Angle) -> &mut Self {
self.rotate_axis(Vec3::new(0.0, 0.0, 1.0), angle)
}
/// Get translation
pub fn get_translation(&self) -> glam::Vec3 {
let (_, _, t) = self.matrix.to_scale_rotation_translation();
t
}
/// Get rotation in radians
pub fn get_rotation_rad(&self) -> glam::Vec3 {
let (_, quat, _) = self.matrix.to_scale_rotation_translation();
let rot = quat.to_euler(glam::EulerRot::XYZ);
rot.into()
}
/// Get rotation in degrees
pub fn get_rotation_deg(&self) -> glam::Vec3 {
let mut rot = self.get_rotation_rad();
rot.x = angle::radians_to_degrees(rot.x);
rot.y = angle::radians_to_degrees(rot.y);
rot.z = angle::radians_to_degrees(rot.z);
rot
}
pub fn scale(&mut self, scale: Vec3) -> &mut Self {
let scale = Mat4::from_scale(scale);
self.matrix *= scale;
self
}
pub fn x(&self) -> f32 {
self.get_translation().x
}
pub fn y(&self) -> f32 {
self.get_translation().y
}
pub fn z(&self) -> f32 {
self.get_translation().z
pub fn rotate_z(&mut self, angle: Angle) {
self.rotate(Quat::from_rotation_z(angle.to_radians()))
}
}

View File

@ -61,17 +61,9 @@ impl RenderCamera {
}
pub fn update_view_projection(&mut self, camera: &CameraComponent) -> &glam::Mat4 {
let rotation = camera.transform.get_rotation_rad();
let position = camera.transform.get_translation();
let (sin_y, cos_y) = rotation.y.sin_cos();
let (sin_z, cos_z) = rotation.z.sin_cos();
let target = glam::Vec3::new(
cos_y * cos_z,
sin_y,
cos_y * sin_z
).normalize();
let position = camera.transform.translation;
let target = camera.transform.rotation * glam::Vec3::new(0.0, 0.0, -1.0);
let target = target.normalize();
/* debug!("Camera rotation: {:?}", rotation);
debug!("Camera position: {:?}", position);

View File

@ -162,7 +162,7 @@ impl BasicRenderer {
let transform_buffer = device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: Some("Transform Buffer"),
contents: bytemuck::cast_slice(&[Transform::new()]),
contents: bytemuck::cast_slice(&[glam::Mat4::IDENTITY]),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
}
);
@ -405,7 +405,7 @@ impl Renderer for BasicRenderer {
}
// Update transform buffer, and bind to the bind group
self.queue.write_buffer(&self.transform_buffer, 0, bytemuck::cast_slice(&[job.transform().matrix()]));
self.queue.write_buffer(&self.transform_buffer, 0, bytemuck::cast_slice(&[job.transform().calculate_mat4()]));
render_pass.set_bind_group(1, &self.transform_bind_group, &[]);
// There will always be a camera (hopefully)