Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
60 changes: 60 additions & 0 deletions examples/minimal_2d.rs
Original file line number Diff line number Diff line change
@@ -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<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
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());
}
27 changes: 25 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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::<GizmoMaterial>::default())
.add_plugin(picking::GizmoPickingPlugin)
Expand Down
153 changes: 82 additions & 71 deletions src/mesh/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
gizmo_material::GizmoMaterial, PickableGizmo, TransformGizmoBundle, TransformGizmoInteraction,
gizmo_material::GizmoMaterial, GizmoAxisMode, GizmoAxisModeValue, PickableGizmo,
TransformGizmoBundle, TransformGizmoInteraction,
};
use bevy::prelude::*;

Expand All @@ -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<GizmoAxisMode>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<GizmoMaterial>>,
) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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(),
Expand All @@ -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(),
Expand Down