Skip to content
This repository has been archived by the owner on Apr 18, 2022. It is now read-only.

Port amethyst_controls to legion. #2325

Closed
wants to merge 9 commits into from
35 changes: 18 additions & 17 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,31 @@ license = "MIT/Apache-2.0"
travis-ci = { repository = "amethyst/amethyst", branch = "master" }

[features]
default = ["animation", "audio", "locale", "network", "renderer"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please revert the changes to this file before the merge happens :)

#default = ["animation", "audio", "locale", "network", "renderer"]
default = ["renderer"]

vulkan = ["amethyst_rendy/vulkan", "amethyst_rendy/vulkan-x11"]
metal = ["amethyst_rendy/metal"]
empty = ["amethyst_rendy/empty"]

tiles = [
"amethyst_tiles"
#"amethyst_tiles"
]
animation = [
"amethyst_animation"
#"amethyst_animation"
]
audio = [
"amethyst_audio"
]
gltf = [
"amethyst_gltf",
"amethyst_animation"
#"amethyst_gltf",
#"amethyst_animation"
]
locale = [
"amethyst_locale"
#"amethyst_locale"
]
network = [
"amethyst_network"
#"amethyst_network"
]

renderer = [
Expand All @@ -52,18 +53,18 @@ renderer = [
profiler = [
"thread_profiler",
"thread_profiler/thread_profiler",
"amethyst_animation/profiler",
#"amethyst_animation/profiler",
"amethyst_assets/profiler",
"amethyst_audio/profiler",
"amethyst_config/profiler",
"amethyst_core/profiler",
"amethyst_controls/profiler",
"amethyst_input/profiler",
"amethyst_locale/profiler",
#"amethyst_locale/profiler",
"amethyst_rendy/profiler",
"amethyst_ui/profiler",
#"amethyst_ui/profiler",
"amethyst_utils/profiler",
"amethyst_tiles/profiler",
#"amethyst_tiles/profiler",
]
sdl_controller = [
"amethyst_input/sdl_controller",
Expand Down Expand Up @@ -108,23 +109,23 @@ members = [
]

[dependencies]
amethyst_animation = { path = "amethyst_animation", version = "0.10.0", optional = true }
#amethyst_animation = { path = "amethyst_animation", version = "0.10.0", optional = true }
amethyst_assets = { path = "amethyst_assets", version = "0.11.0" }
amethyst_audio = { path = "amethyst_audio", version = "0.10.0", optional = true }
amethyst_config = { path = "amethyst_config", version = "0.14.0" }
amethyst_core = { path = "amethyst_core", version = "0.10.0" }
amethyst_error = { path = "amethyst_error", version = "0.5.0" }
amethyst_controls = { path = "amethyst_controls", version = "0.9.0" }
amethyst_derive = { path = "amethyst_derive", version = "0.8.0" }
amethyst_gltf = { path = "amethyst_gltf", version = "0.10.0", optional = true }
amethyst_network = { path = "amethyst_network", version = "0.8.0", optional = true }
amethyst_locale = { path = "amethyst_locale", version = "0.9.0", optional = true }
#amethyst_gltf = { path = "amethyst_gltf", version = "0.10.0", optional = true }
#amethyst_network = { path = "amethyst_network", version = "0.8.0", optional = true }
#amethyst_locale = { path = "amethyst_locale", version = "0.9.0", optional = true }
amethyst_rendy = { path = "amethyst_rendy", version = "0.5.0", features = ["window"], optional = true }
amethyst_input = { path = "amethyst_input", version = "0.11.0" }
amethyst_ui = { path = "amethyst_ui", version = "0.10.0" }
#amethyst_ui = { path = "amethyst_ui", version = "0.10.0" }
amethyst_utils = { path = "amethyst_utils", version = "0.10.0" }
amethyst_window = { path = "amethyst_window", version = "0.5.0" }
amethyst_tiles = { path = "amethyst_tiles", version = "0.3.0", optional = true }
#amethyst_tiles = { path = "amethyst_tiles", version = "0.3.0", optional = true }
crossbeam-channel = "0.4.2"
derivative = "2.1.1"
fern = { version = "0.6.0", features = ["colored"] }
Expand Down
89 changes: 35 additions & 54 deletions amethyst_controls/src/bundles.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::marker::PhantomData;

use amethyst_core::{
bundle::SystemBundle,
ecs::prelude::{DispatcherBuilder, World},
dispatcher::{DispatcherBuilder, Stage, SystemBundle},
ecs::prelude::*,
math::one,
SystemDesc,
};
use amethyst_error::Error;
use amethyst_input::BindingTypes;
Expand Down Expand Up @@ -37,25 +36,25 @@ pub struct FlyControlBundle<T: BindingTypes> {
sensitivity_x: f32,
sensitivity_y: f32,
speed: f32,
right_input_axis: Option<T::Axis>,
up_input_axis: Option<T::Axis>,
forward_input_axis: Option<T::Axis>,
horizontal_axis: Option<T::Axis>,
vertical_axis: Option<T::Axis>,
longitudinal_axis: Option<T::Axis>,
}

impl<T: BindingTypes> FlyControlBundle<T> {
/// Builds a new fly control bundle using the provided axes as controls.
pub fn new(
right_input_axis: Option<T::Axis>,
up_input_axis: Option<T::Axis>,
forward_input_axis: Option<T::Axis>,
horizontal_axis: Option<T::Axis>,
vertical_axis: Option<T::Axis>,
longitudinal_axis: Option<T::Axis>,
) -> Self {
FlyControlBundle {
sensitivity_x: 1.0,
sensitivity_y: 1.0,
speed: one(),
right_input_axis,
up_input_axis,
forward_input_axis,
horizontal_axis,
vertical_axis,
longitudinal_axis,
}
}

Expand All @@ -73,38 +72,28 @@ impl<T: BindingTypes> FlyControlBundle<T> {
}
}

impl<'a, 'b, T: BindingTypes> SystemBundle<'a, 'b> for FlyControlBundle<T> {
impl<T: BindingTypes> SystemBundle for FlyControlBundle<T> {
fn build(
self,
world: &mut World,
builder: &mut DispatcherBuilder<'a, 'b>,
resources: &mut Resources,
builder: &mut DispatcherBuilder<'_>,
) -> Result<(), Error> {
builder.add(
FlyMovementSystemDesc::<T>::new(
builder.add_system(
Stage::Begin,
build_fly_movement_system::<T>(
self.speed,
self.right_input_axis,
self.up_input_axis,
self.forward_input_axis,
)
.build(world),
"fly_movement",
&[],
self.horizontal_axis,
self.vertical_axis,
self.longitudinal_axis,
),
);
builder.add(
FreeRotationSystemDesc::new(self.sensitivity_x, self.sensitivity_y).build(world),
"free_rotation",
&[],
);
builder.add(
MouseFocusUpdateSystemDesc::default().build(world),
"mouse_focus",
&["free_rotation"],
);
builder.add(
CursorHideSystemDesc::default().build(world),
"cursor_hide",
&["mouse_focus"],
builder.add_system(
Stage::Begin,
build_free_rotation_system(self.sensitivity_x, self.sensitivity_y),
);
builder.add_system(Stage::Begin, build_mouse_focus_update_system);
builder.add_system(Stage::Begin, build_cursor_hide_system);
Ok(())
}
}
Expand Down Expand Up @@ -147,28 +136,20 @@ impl<T: BindingTypes> Default for ArcBallControlBundle<T> {
}
}

impl<'a, 'b, T: BindingTypes> SystemBundle<'a, 'b> for ArcBallControlBundle<T> {
impl<T: BindingTypes> SystemBundle for ArcBallControlBundle<T> {
fn build(
self,
world: &mut World,
builder: &mut DispatcherBuilder<'a, 'b>,
resources: &mut Resources,
builder: &mut DispatcherBuilder<'_>,
) -> Result<(), Error> {
builder.add(ArcBallRotationSystem::default(), "arc_ball_rotation", &[]);
builder.add(
FreeRotationSystemDesc::new(self.sensitivity_x, self.sensitivity_y).build(world),
"free_rotation",
&[],
);
builder.add(
MouseFocusUpdateSystemDesc::default().build(world),
"mouse_focus",
&["free_rotation"],
);
builder.add(
CursorHideSystemDesc::default().build(world),
"cursor_hide",
&["mouse_focus"],
builder.add_system(
Stage::Begin,
build_free_rotation_system(self.sensitivity_x, self.sensitivity_y),
);
builder.add_system(Stage::Begin, build_arc_ball_rotation_system);
builder.add_system(Stage::Begin, build_mouse_focus_update_system);
builder.add_system(Stage::Begin, build_cursor_hide_system);
Ok(())
}
}
92 changes: 43 additions & 49 deletions amethyst_controls/src/components.rs
Original file line number Diff line number Diff line change
@@ -1,67 +1,61 @@
use amethyst_assets::PrefabData;
use amethyst_core::ecs::prelude::{Component, Entity, HashMapStorage, NullStorage, WriteStorage};
use amethyst_core::ecs::prelude::*;
use amethyst_error::Error;

use serde::{Deserialize, Serialize};

/// Add this to a camera if you want it to be a fly camera.
/// You need to add the FlyControlBundle or the required systems for it to work.
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
pub struct FlyControlTag;

impl Component for FlyControlTag {
type Storage = NullStorage<FlyControlTag>;
}
pub struct FlyControl;

/// To add an arc ball behaviour, add this to a camera which already has the FlyControlTag added.
#[derive(Debug, Clone)]
pub struct ArcBallControlTag {
pub struct ArcBallControl {
/// The target entity which the camera will orbit
pub target: Entity,
/// The distance from the target entity that the camera should orbit at.
pub distance: f32,
}

impl Component for ArcBallControlTag {
// we can use HashMapStorage here because, according to the specs doc, this storage should be
// use when the component is used with few entity, I think there will rarely more than one
// camera
type Storage = HashMapStorage<ArcBallControlTag>;
}

/// `PrefabData` for loading control tags on an `Entity`
///
/// Will always load a `FlyControlTag`
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
pub struct ControlTagPrefab {
/// Place `ArcBallControlTag` on the `Entity`
pub arc_ball: Option<(usize, f32)>,
}

impl<'a> PrefabData<'a> for ControlTagPrefab {
type SystemData = (
WriteStorage<'a, FlyControlTag>,
WriteStorage<'a, ArcBallControlTag>,
);
type Result = ();

fn add_to_entity(
&self,
entity: Entity,
system_data: &mut Self::SystemData,
entities: &[Entity],
_: &[Entity],
) -> Result<(), Error> {
system_data.0.insert(entity, FlyControlTag)?;
if let Some((index, distance)) = self.arc_ball {
system_data.1.insert(
entity,
ArcBallControlTag {
target: entities[index],
distance,
},
)?;
}
Ok(())
impl ArcBallControl {
pub fn new(target: Entity, distance: f32) -> Self {
ArcBallControl { target, distance }
}
}

// `PrefabData` for loading control tags on an `Entity`
//
// Will always load a `FlyControlTag`
// #[derive(Debug, Default, Clone, Deserialize, Serialize)]
// pub struct ControlTagPrefab {
// /// Place `ArcBallControlTag` on the `Entity`
// pub arc_ball: Option<(usize, f32)>,
// }
//
// impl<'a> PrefabData<'a> for ControlTagPrefab {
// type SystemData = (
// WriteStorage<'a, FlyControl>,
// WriteStorage<'a, ArcBallControl>,
// );
// type Result = ();
//
// fn add_to_entity(
// &self,
// entity: Entity,
// system_data: &mut Self::SystemData,
// entities: &[Entity],
// _: &[Entity],
// ) -> Result<(), Error> {
// system_data.0.insert(entity, FlyControl)?;
// if let Some((index, distance)) = self.arc_ball {
// system_data.1.insert(
// entity,
// ArcBallControl {
// target: entities[index],
// distance,
// },
// )?;
// }
// Ok(())
// }
// }
7 changes: 3 additions & 4 deletions amethyst_controls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@

pub use self::{
bundles::{ArcBallControlBundle, FlyControlBundle},
components::{ArcBallControlTag, ControlTagPrefab, FlyControlTag},
components::{ArcBallControl, FlyControl},
resources::{HideCursor, WindowFocus},
systems::{
ArcBallRotationSystem, CursorHideSystem, CursorHideSystemDesc, FlyMovementSystem,
FlyMovementSystemDesc, FreeRotationSystem, FreeRotationSystemDesc, MouseFocusUpdateSystem,
MouseFocusUpdateSystemDesc,
build_arc_ball_rotation_system, build_cursor_hide_system, build_fly_movement_system,
build_free_rotation_system, build_mouse_focus_update_system,
},
};

Expand Down
Loading