diff --git a/engine/src/scene/content/components/draw.rs b/engine/src/scene/content/components/draw.rs index 4f3d759..65f3bb8 100644 --- a/engine/src/scene/content/components/draw.rs +++ b/engine/src/scene/content/components/draw.rs @@ -1,6 +1,8 @@ use crate::prelude::*; +use anyhow::Result; use asset::AssetMesh; +use context::prelude::cgmath::Matrix4; use std::{ ops::{Index, IndexMut}, @@ -74,6 +76,13 @@ impl Draw { self.meshes.iter_mut() } + pub fn set_transform(&self, transform: Matrix4) -> Result<()> { + self.iter().try_for_each(|mesh| { + mesh.model_buffer() + .fill(&[(transform * mesh.model_matrix()).into()]) + }) + } + pub fn len(&self) -> usize { self.meshes.len() } diff --git a/engine/src/scene/content/components/free_space_control.rs b/engine/src/scene/content/components/free_space_control.rs index c084204..8a8a13d 100644 --- a/engine/src/scene/content/components/free_space_control.rs +++ b/engine/src/scene/content/components/free_space_control.rs @@ -140,7 +140,7 @@ impl FreeSpaceControl { self.add_rotation(rotation_changes); self.position += rotated_position_changes; - Some(Matrix4::from(self.rotation_matrix()) * Matrix4::from_translation(self.position)) + Some(Matrix4::from_translation(self.position) * Matrix4::from(self.rotation_matrix())) } #[rustfmt::skip] diff --git a/engine/src/scene/content/components/location.rs b/engine/src/scene/content/components/location.rs index 1b54a8c..688d914 100644 --- a/engine/src/scene/content/components/location.rs +++ b/engine/src/scene/content/components/location.rs @@ -174,8 +174,8 @@ impl Location { * Matrix4::from_nonuniform_scale(self.scale.x, self.scale.y, self.scale.z); } - pub fn transformation_matrix(&self) -> &Matrix4 { - &self.transformation + pub fn transformation_matrix(&self) -> Matrix4 { + self.transformation } fn update_apply(&mut self) -> Result<()> { @@ -208,15 +208,10 @@ impl Location { pub unsafe fn apply_model_matrices( &self, - transformation: &Matrix4, + transformation: Matrix4, draw: &Draw, ) -> Result<()> { - for mesh in draw.iter() { - mesh.model_buffer() - .fill(&[(transformation * mesh.model_matrix()).into()])?; - } - - Ok(()) + draw.set_transform(transformation) } } diff --git a/examples/free_space/src/game.rs b/examples/free_space/src/game.rs index 7437d81..25f7159 100644 --- a/examples/free_space/src/game.rs +++ b/examples/free_space/src/game.rs @@ -1,8 +1,88 @@ +use std::collections::HashMap; + use anyhow::Result; use ecs::*; use engine::prelude::*; +#[derive(Clone, Copy, Debug)] +struct PlayerEntity(Entity); + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +enum Input { + Axis(u8), + Button(Button), +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +enum Button { + One, +} + +#[derive(Clone, Copy, Debug)] +enum Control { + Throttle, + StrafeHorizontal, + StrafeVertical, + Yaw, + Pitch, + Roll, + + PrimaryWeapon, + SecondaryWeapon, +} + +#[derive(Clone, Debug)] +struct ControllerSettings { + mappings: HashMap<(String, Input), Control>, +} + +impl Default for ControllerSettings { + fn default() -> Self { + Self { + mappings: [ + ( + ("Controller 1".to_string(), Input::Axis(0)), + Control::Throttle, + ), + ( + ("Controller 1".to_string(), Input::Axis(1)), + Control::StrafeHorizontal, + ), + ( + ("Controller 1".to_string(), Input::Axis(2)), + Control::StrafeVertical, + ), + (("Controller 1".to_string(), Input::Axis(3)), Control::Pitch), + ( + ("Controller 1".to_string(), Input::Button(Button::One)), + Control::PrimaryWeapon, + ), + (("Controller 2".to_string(), Input::Axis(1)), Control::Yaw), + (("Controller 2".to_string(), Input::Axis(0)), Control::Roll), + ( + ("Controller 2".to_string(), Input::Button(Button::One)), + Control::SecondaryWeapon, + ), + ] + .into_iter() + .collect(), + } + } +} + +impl ControllerSettings { + pub fn map_axis( + &self, + controller_name: impl ToString, + axes: ControllerAxis, + ) -> Vec<(Control, f32)> { + self.mappings + .get(&controller_name.to_string()) + .map(|control| *control) + } +} + pub struct Game; impl Game { @@ -11,6 +91,9 @@ impl Game { } pub fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> { + let player = world.resources.get::(); + let fighter_object = world.entity_mut(player.0)?; + match event { EngineEvent::MouseButtonDown(MouseButton::Left) => { let camera_control = world.resources.get_mut::(); @@ -28,6 +111,8 @@ impl Game { camera_control.mouse_move(x, y, scene.view_mut())?; } + EngineEvent::ControllerAxis(controller, axis) => {} + _ => (), } @@ -37,7 +122,38 @@ impl Game { impl Game { pub fn setup_updates(world_builder: &mut WorldBuilder) -> Result<()> { - world_builder.add_update(name, priority, func, filter)?; + world_builder.add_update( + "player_rotation", + 200, + Self::player_orientation, + EmptyFilter, + )?; + + Ok(()) + } + + pub fn setup_scene(world: &mut World) -> Result<()> { + let mut fighter = AssetHandler::create(world).create_entity("fighter")?; + fighter.insert_component(FreeSpaceControl::new(FreeSpaceControlSettings::default())); + + let player = PlayerEntity(world.add_entity(fighter)?); + world.resources.insert(player); + + world.commit_entity_changes() + } +} + +// updates +impl Game { + fn player_orientation( + world: &mut World, + _entity: Entity, + draw: &mut Draw, + control: &mut FreeSpaceControl, + ) -> Result<()> { + if let Some(transform) = control.update(world.now()) { + draw.set_transform(transform)?; + } Ok(()) } diff --git a/examples/free_space/src/main.rs b/examples/free_space/src/main.rs index ed1fe8c..76ee6a7 100644 --- a/examples/free_space/src/main.rs +++ b/examples/free_space/src/main.rs @@ -39,6 +39,8 @@ fn main() -> Result<()> { world_builder.resources.insert(camera_control); Game::setup_updates(&mut world_builder)?; + let mut world = world_builder.build(); + Game::setup_scene(&mut world)?; - world_builder.build().run() + world.run() }