implement simple ecs systems
This commit is contained in:
parent
6a30a17f5f
commit
1ef664165d
|
@ -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,
|
||||
}
|
||||
|
|
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 {
|
||||
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),
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -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(())
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue