implement simple ecs systems
This commit is contained in:
parent
6a30a17f5f
commit
1ef664165d
|
@ -11,7 +11,7 @@ pub struct CameraComponent {
|
||||||
impl Default for CameraComponent {
|
impl Default for CameraComponent {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
transform: Transform::new(),
|
transform: Transform::default(),
|
||||||
fov: Angle::Degrees(45.0),
|
fov: Angle::Degrees(45.0),
|
||||||
mode: CameraProjectionMode::Perspective,
|
mode: CameraProjectionMode::Perspective,
|
||||||
}
|
}
|
||||||
|
|
16
src/game.rs
16
src/game.rs
|
@ -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 {
|
struct GameLoop {
|
||||||
window: Arc<Window>,
|
window: Arc<Window>,
|
||||||
|
@ -96,9 +83,6 @@ struct GameLoop {
|
||||||
|
|
||||||
impl GameLoop {
|
impl GameLoop {
|
||||||
pub async fn new(window: Arc<Window>, world: Arc<Mutex<World>>, user_systems: Vec<Box<dyn SimpleSystem>>) -> 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 {
|
Self {
|
||||||
window: Arc::clone(&window),
|
window: Arc::clone(&window),
|
||||||
renderer: Box::new(BasicRenderer::create_with_window(window).await),
|
renderer: Box::new(BasicRenderer::create_with_window(window).await),
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -10,6 +10,7 @@ use ecs::components::mesh::MeshComponent;
|
||||||
use ecs::components::transform::TransformComponent;
|
use ecs::components::transform::TransformComponent;
|
||||||
use game::Game;
|
use game::Game;
|
||||||
use hecs::World;
|
use hecs::World;
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::ecs::SystemFnExecutor;
|
use crate::ecs::SystemFnExecutor;
|
||||||
use crate::render::material::Material;
|
use crate::render::material::Material;
|
||||||
|
@ -78,11 +79,11 @@ async fn main() {
|
||||||
shader_id: 0,
|
shader_id: 0,
|
||||||
texture: diffuse_texture
|
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();
|
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_y(Angle::Degrees(-25.0));
|
||||||
camera.transform.rotate_z(Angle::Degrees(-90.0));
|
camera.transform.rotate_z(Angle::Degrees(-90.0));
|
||||||
world.spawn((camera,));
|
world.spawn((camera,));
|
||||||
|
@ -90,7 +91,11 @@ async fn main() {
|
||||||
let jiggle_system = |world: &mut World| -> anyhow::Result<()> {
|
let jiggle_system = |world: &mut World| -> anyhow::Result<()> {
|
||||||
for (_eid, (transform, )) in world.query_mut::<(&mut TransformComponent,)>() {
|
for (_eid, (transform, )) in world.query_mut::<(&mut TransformComponent,)>() {
|
||||||
let t = &mut transform.transform;
|
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(())
|
Ok(())
|
||||||
|
|
|
@ -3,186 +3,75 @@ use glam::{Vec3, Mat4, Quat};
|
||||||
use crate::math::angle::{self, Angle};
|
use crate::math::angle::{self, Angle};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct Transform {
|
pub struct Transform {
|
||||||
matrix: glam::Mat4,
|
pub translation: Vec3,
|
||||||
|
pub rotation: Quat,
|
||||||
|
pub scale: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Transform {
|
impl Default for Transform {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
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 {
|
fn into(self) -> glam::Mat4 {
|
||||||
self.matrix
|
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)]
|
#[allow(dead_code)]
|
||||||
impl Transform {
|
impl Transform {
|
||||||
pub fn new() -> Self {
|
pub fn new(translation: Vec3, rotation: Quat, scale: Vec3) -> Self {
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_matrix(matrix: glam::Mat4) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
matrix,
|
translation,
|
||||||
|
rotation,
|
||||||
|
scale,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn matrix(&self) -> glam::Mat4 {
|
pub fn from_translation(translation: Vec3) -> Self {
|
||||||
self.matrix
|
Self::new(translation, Quat::IDENTITY, ONE_V3)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create Transform from scale, rotation (in degrees), and translation
|
pub fn from_xyz(x: f32, y: f32, z: f32) -> Self {
|
||||||
pub fn from_scale_rotation_deg_translation(scale: Vec3, mut rotation: Vec3, translation: Vec3) -> Self {
|
Self::new(Vec3::new(x, y, z), Quat::IDENTITY, ONE_V3)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create Transform from scale, rotation (in radians), and translation
|
pub fn calculate_mat4(&self) -> Mat4 {
|
||||||
pub fn from_scale_rotation_rad_translation(scale: Vec3, rotation: Vec3, translation: Vec3) -> Self {
|
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create Transform from scale, rotation (as a quaternion), and translation
|
/// Get the forward vector of the Transform.
|
||||||
pub fn from_scale_rotation_quat_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self {
|
pub fn forward(&self) -> Vec3 {
|
||||||
let matrix = glam::Mat4::from_scale_rotation_translation(scale, rotation, translation);
|
self.rotation * ONE_V3
|
||||||
|
|
||||||
Self::from_matrix(matrix)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_translation_vec(translation: Vec3) -> Self {
|
/// Rotate this transform using a Quaternion
|
||||||
let matrix = glam::Mat4::from_scale_rotation_translation(Vec3::new(1.0, 1.0, 1.0), Quat::IDENTITY, translation);
|
pub fn rotate(&mut self, rotation: Quat) {
|
||||||
|
self.rotation = rotation * self.rotation;
|
||||||
Self::from_matrix(matrix)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_translation(x: f32, y: f32, z: f32) -> Self {
|
pub fn rotate_x(&mut self, angle: Angle) {
|
||||||
Self::from_translation_vec(Vec3::new(x, y, z))
|
self.rotate(Quat::from_rotation_x(angle.to_radians()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn translate_vec3(&mut self, vec: Vec3) -> &mut Self {
|
pub fn rotate_y(&mut self, angle: Angle) {
|
||||||
let translation = glam::Mat4::from_translation(vec);
|
self.rotate(Quat::from_rotation_y(angle.to_radians()))
|
||||||
self.matrix *= translation;
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate around the given axis.
|
pub fn rotate_z(&mut self, angle: Angle) {
|
||||||
pub fn rotate_axis(&mut self, axis: Vec3, angle: Angle) -> &mut Self {
|
self.rotate(Quat::from_rotation_z(angle.to_radians()))
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -61,17 +61,9 @@ impl RenderCamera {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_view_projection(&mut self, camera: &CameraComponent) -> &glam::Mat4 {
|
pub fn update_view_projection(&mut self, camera: &CameraComponent) -> &glam::Mat4 {
|
||||||
let rotation = camera.transform.get_rotation_rad();
|
let position = camera.transform.translation;
|
||||||
let position = camera.transform.get_translation();
|
let target = camera.transform.rotation * glam::Vec3::new(0.0, 0.0, -1.0);
|
||||||
|
let target = target.normalize();
|
||||||
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();
|
|
||||||
|
|
||||||
/* debug!("Camera rotation: {:?}", rotation);
|
/* debug!("Camera rotation: {:?}", rotation);
|
||||||
debug!("Camera position: {:?}", position);
|
debug!("Camera position: {:?}", position);
|
||||||
|
|
|
@ -162,7 +162,7 @@ impl BasicRenderer {
|
||||||
let transform_buffer = device.create_buffer_init(
|
let transform_buffer = device.create_buffer_init(
|
||||||
&wgpu::util::BufferInitDescriptor {
|
&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Transform Buffer"),
|
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,
|
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
|
// 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, &[]);
|
render_pass.set_bind_group(1, &self.transform_bind_group, &[]);
|
||||||
|
|
||||||
// There will always be a camera (hopefully)
|
// There will always be a camera (hopefully)
|
||||||
|
|
Loading…
Reference in New Issue