From b9fbdf197fbc9d623903ef447fd4cbeacf4ee987 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Fri, 28 Jan 2022 18:39:14 +0100 Subject: [PATCH] wip: #8 2d axis only --- examples/minimal.rs | 1 + examples/minimal_2d.rs | 60 ++++++++++++++++ src/lib.rs | 27 +++++++- src/mesh/mod.rs | 153 ++++++++++++++++++++++------------------- 4 files changed, 168 insertions(+), 73 deletions(-) create mode 100644 examples/minimal_2d.rs diff --git a/examples/minimal.rs b/examples/minimal.rs index 0518c50..a486c76 100644 --- a/examples/minimal.rs +++ b/examples/minimal.rs @@ -11,6 +11,7 @@ fn main() { .add_plugins(bevy_mod_picking::DefaultPickingPlugins) .add_plugin(bevy_transform_gizmo::TransformGizmoPlugin::new( Quat::from_rotation_y(-0.2), // Align the gizmo to a different coordinate system. + bevy_transform_gizmo::GizmoAxisModeValue::XYZ, )) // Use TransformGizmoPlugin::default() to align to the scene's coordinate system. .add_startup_system(setup) .run(); diff --git a/examples/minimal_2d.rs b/examples/minimal_2d.rs new file mode 100644 index 0000000..d735b58 --- /dev/null +++ b/examples/minimal_2d.rs @@ -0,0 +1,60 @@ +use bevy::prelude::*; + +fn main() { + App::new() + .insert_resource(WindowDescriptor { + vsync: false, // Disabled for this demo to remove vsync as a source of input latency + ..Default::default() + }) + .add_plugins(DefaultPlugins) + .add_plugins(bevy_mod_picking::DefaultPickingPlugins) + .add_plugin(bevy_transform_gizmo::TransformGizmoPlugin::new( + Quat::default(), + bevy_transform_gizmo::GizmoAxisModeValue::XY, + )) + .add_startup_system(setup) + .run(); +} + +/// set up a simple 2D scene +fn setup( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + commands.insert_resource(bevy_transform_gizmo::GizmoAxisMode { + mode: bevy_transform_gizmo::GizmoAxisModeValue::XY, + }); + // plane + commands + .spawn_bundle(PbrBundle { + mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })), + material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), + ..Default::default() + }) + .insert_bundle(bevy_mod_picking::PickableBundle::default()) + .insert(bevy_transform_gizmo::GizmoTransformable); + // cube + commands + .spawn_bundle(PbrBundle { + mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), + material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), + transform: Transform::from_xyz(0.0, 0.5, 0.0), + ..Default::default() + }) + .insert_bundle(bevy_mod_picking::PickableBundle::default()) + .insert(bevy_transform_gizmo::GizmoTransformable); + // light + commands.spawn_bundle(PointLightBundle { + transform: Transform::from_xyz(4.0, 8.0, 4.0), + ..Default::default() + }); + // camera + commands + .spawn_bundle(PerspectiveCameraBundle { + transform: Transform::from_xyz(2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y), + ..Default::default() + }) + .insert_bundle(bevy_mod_picking::PickingCameraBundle::default()) + .insert(bevy_transform_gizmo::GizmoPickSource::default()); +} diff --git a/src/lib.rs b/src/lib.rs index 99b3c80..64a33ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,15 +52,35 @@ pub struct GizmoSettings { pub alignment_rotation: Quat, } +#[derive(PartialEq, Clone, Copy)] +pub enum GizmoAxisModeValue { + XYZ, + XY, +} + +impl Default for GizmoAxisModeValue { + fn default() -> Self { + GizmoAxisModeValue::XYZ + } +} + +pub struct GizmoAxisMode { + pub mode: GizmoAxisModeValue, +} + #[derive(Default)] pub struct TransformGizmoPlugin { // Rotation to apply to the gizmo when it is placed. Used to align the gizmo to a different // coordinate system. alignment_rotation: Quat, + axis_mode: GizmoAxisModeValue, } impl TransformGizmoPlugin { - pub fn new(alignment_rotation: Quat) -> Self { - TransformGizmoPlugin { alignment_rotation } + pub fn new(alignment_rotation: Quat, axis_mode: GizmoAxisModeValue) -> Self { + TransformGizmoPlugin { + alignment_rotation, + axis_mode, + } } } impl Plugin for TransformGizmoPlugin { @@ -72,6 +92,9 @@ impl Plugin for TransformGizmoPlugin { ); let alignment_rotation = self.alignment_rotation; app.insert_resource(GizmoSettings { alignment_rotation }) + .insert_resource(GizmoAxisMode { + mode: self.axis_mode, + }) .insert_resource(GizmoSystemsEnabled(true)) .add_plugin(MaterialPlugin::::default()) .add_plugin(picking::GizmoPickingPlugin) diff --git a/src/mesh/mod.rs b/src/mesh/mod.rs index 15dda45..9761dc1 100644 --- a/src/mesh/mod.rs +++ b/src/mesh/mod.rs @@ -1,5 +1,6 @@ use crate::{ - gizmo_material::GizmoMaterial, PickableGizmo, TransformGizmoBundle, TransformGizmoInteraction, + gizmo_material::GizmoMaterial, GizmoAxisMode, GizmoAxisModeValue, PickableGizmo, + TransformGizmoBundle, TransformGizmoInteraction, }; use bevy::prelude::*; @@ -9,6 +10,7 @@ mod truncated_torus; /// Startup system that builds the procedural mesh and materials of the gizmo. pub fn build_gizmo( mut commands: Commands, + axis_mode: Res, mut meshes: ResMut>, mut materials: ResMut>, ) { @@ -71,15 +73,17 @@ pub fn build_gizmo( )), ..Default::default() }); - parent.spawn_bundle(MaterialMeshBundle { - mesh: arrow_tail_mesh, - material: gizmo_matl_z.clone(), - transform: Transform::from_matrix(Mat4::from_rotation_translation( - Quat::from_rotation_x(std::f32::consts::PI / 2.0), - Vec3::new(0.0, 0.0, axis_length / 2.0), - )), - ..Default::default() - }); + if axis_mode.mode != GizmoAxisModeValue::XY { + parent.spawn_bundle(MaterialMeshBundle { + mesh: arrow_tail_mesh, + material: gizmo_matl_z.clone(), + transform: Transform::from_matrix(Mat4::from_rotation_translation( + Quat::from_rotation_x(std::f32::consts::PI / 2.0), + Vec3::new(0.0, 0.0, axis_length / 2.0), + )), + ..Default::default() + }); + } // Translation Handles parent @@ -109,21 +113,23 @@ pub fn build_gizmo( original: Vec3::Y, axis: Vec3::Y, }); - parent - .spawn_bundle(MaterialMeshBundle { - mesh: cone_mesh.clone(), - material: gizmo_matl_z_sel.clone(), - transform: Transform::from_matrix(Mat4::from_rotation_translation( - Quat::from_rotation_x(std::f32::consts::PI / 2.0), - Vec3::new(0.0, 0.0, axis_length), - )), - ..Default::default() - }) - .insert(PickableGizmo::default()) - .insert(TransformGizmoInteraction::TranslateAxis { - original: Vec3::Z, - axis: Vec3::Z, - }); + if axis_mode.mode != GizmoAxisModeValue::XY { + parent + .spawn_bundle(MaterialMeshBundle { + mesh: cone_mesh.clone(), + material: gizmo_matl_z_sel.clone(), + transform: Transform::from_matrix(Mat4::from_rotation_translation( + Quat::from_rotation_x(std::f32::consts::PI / 2.0), + Vec3::new(0.0, 0.0, axis_length), + )), + ..Default::default() + }) + .insert(PickableGizmo::default()) + .insert(TransformGizmoInteraction::TranslateAxis { + original: Vec3::Z, + axis: Vec3::Z, + }); + } /* // Origin parent @@ -136,20 +142,23 @@ pub fn build_gizmo( .insert(TransformGizmoInteraction::TranslateOrigin); */ // Rotation Arcs - parent.spawn_bundle(MaterialMeshBundle { - mesh: rotation_mesh.clone(), - material: gizmo_matl_x.clone(), - transform: Transform::from_rotation(Quat::from_axis_angle( - Vec3::Z, - f32::to_radians(90.0), - )), - ..Default::default() - }); - parent.spawn_bundle(MaterialMeshBundle { - mesh: rotation_mesh.clone(), - material: gizmo_matl_y.clone(), - ..Default::default() - }); + + if axis_mode.mode != GizmoAxisModeValue::XY { + parent.spawn_bundle(MaterialMeshBundle { + mesh: rotation_mesh.clone(), + material: gizmo_matl_x.clone(), + transform: Transform::from_rotation(Quat::from_axis_angle( + Vec3::Z, + f32::to_radians(90.0), + )), + ..Default::default() + }); + parent.spawn_bundle(MaterialMeshBundle { + mesh: rotation_mesh.clone(), + material: gizmo_matl_y.clone(), + ..Default::default() + }); + } parent.spawn_bundle(MaterialMeshBundle { mesh: rotation_mesh.clone(), material: gizmo_matl_z.clone(), @@ -161,38 +170,40 @@ pub fn build_gizmo( }); // Rotation Handles - parent - .spawn_bundle(MaterialMeshBundle { - mesh: sphere_mesh.clone(), - material: gizmo_matl_x_sel.clone(), - transform: Transform::from_translation(Vec3::new( - 0.0, - f32::to_radians(45.0).sin() * arc_radius, - f32::to_radians(45.0).sin() * arc_radius, - )), - ..Default::default() - }) - .insert(PickableGizmo::default()) - .insert(TransformGizmoInteraction::RotateAxis { - original: Vec3::X, - axis: Vec3::X, - }); - parent - .spawn_bundle(MaterialMeshBundle { - mesh: sphere_mesh.clone(), - material: gizmo_matl_y_sel.clone(), - transform: Transform::from_translation(Vec3::new( - f32::to_radians(45.0).sin() * arc_radius, - 0.0, - f32::to_radians(45.0).sin() * arc_radius, - )), - ..Default::default() - }) - .insert(PickableGizmo::default()) - .insert(TransformGizmoInteraction::RotateAxis { - original: Vec3::Y, - axis: Vec3::Y, - }); + if axis_mode.mode != GizmoAxisModeValue::XY { + parent + .spawn_bundle(MaterialMeshBundle { + mesh: sphere_mesh.clone(), + material: gizmo_matl_x_sel.clone(), + transform: Transform::from_translation(Vec3::new( + 0.0, + f32::to_radians(45.0).sin() * arc_radius, + f32::to_radians(45.0).sin() * arc_radius, + )), + ..Default::default() + }) + .insert(PickableGizmo::default()) + .insert(TransformGizmoInteraction::RotateAxis { + original: Vec3::X, + axis: Vec3::X, + }); + parent + .spawn_bundle(MaterialMeshBundle { + mesh: sphere_mesh.clone(), + material: gizmo_matl_y_sel.clone(), + transform: Transform::from_translation(Vec3::new( + f32::to_radians(45.0).sin() * arc_radius, + 0.0, + f32::to_radians(45.0).sin() * arc_radius, + )), + ..Default::default() + }) + .insert(PickableGizmo::default()) + .insert(TransformGizmoInteraction::RotateAxis { + original: Vec3::Y, + axis: Vec3::Y, + }); + } parent .spawn_bundle(MaterialMeshBundle { mesh: sphere_mesh.clone(),