Skip to content

Commit 730a8a0

Browse files
committed
Add Vpeol3dSnapToPlane
1 parent decb51d commit 730a8a0

File tree

5 files changed

+43
-7
lines changed

5 files changed

+43
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
4848
- UI editing support for `Vpeol3dScale` with separate X, Y, Z drag values.
4949
- UI editing support for `Vpeol2dRotatation` using degrees.
5050
- UI editing support for `Vpeol2dScale` with separate X, Y drag values.
51+
- `Vpeol3dSnapToPlane` to force an entity on a specific plane.
5152

5253
### Changed
5354
- Improved editor ergonomics with better organized workspace instead of single

assets/levels3d/example.yol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"format_version":2,"app_format_version":0},{},[[{"type":"Planet","name":"","uuid":"c8aa8fdd-5431-473c-8774-b069c95f794f"},{"PlanetSettings":{"radius":1.0},"Vpeol3dPosition":[-7.047080993652344,6.785710334777832,0.0]}],[{"type":"Planet","name":"","uuid":"2d676a47-146f-49f0-bba7-cf58a8833b1f"},{"PlanetSettings":{"radius":1.0},"Vpeol3dPosition":[16.688783645629883,-3.0687923431396484,0.0]}],[{"type":"PlanetPointer","name":""},{"LaserPointer":{"target":{"uuid":"c8aa8fdd-5431-473c-8774-b069c95f794f"}},"Vpeol3dPosition":[15.614945411682129,-6.67572021484375e-6,-34.80355453491211]}],[{"type":"Spaceship","name":""},{"SpaceshipSettings":{"enabled":true,"rotation_speed":2.0,"speed":2.0},"Vpeol3dPosition":[1.2451118230819702,-2.86102294921875e-6,21.062850952148438]}]]]
1+
[{"format_version":2,"app_format_version":0},{},[[{"type":"Planet","name":"","uuid":"c8aa8fdd-5431-473c-8774-b069c95f794f"},{"Vpeol3dPosition":[-7.047080993652344,6.785710334777832,0.0],"Vpeol3dRotation":[0.0,0.0,0.0,1.0],"Vpeol3dScale":[1.0,1.0,1.0]}],[{"type":"Planet","name":"","uuid":"2d676a47-146f-49f0-bba7-cf58a8833b1f"},{"Vpeol3dPosition":[16.688783645629883,-3.0687923431396484,0.0],"Vpeol3dRotation":[0.0,0.0,0.0,1.0],"Vpeol3dScale":[1.0,1.0,1.0]}],[{"type":"Spaceship","name":""},{"SpaceshipSettings":{"enabled":true,"rotation_speed":2.0,"speed":2.0},"Vpeol3dPosition":[1.2451118230819702,-2.86102294921875e-6,21.062850952148438]}],[{"type":"PlanetPointer","name":""},{"LaserPointer":{"target":{"uuid":"c8aa8fdd-5431-473c-8774-b069c95f794f"}},"Vpeol3dPosition":[3.227558135986328,2.0,-29.523635864257812]}]]]

examples/example3d.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ fn main() {
7171
.with::<Vpeol3dPosition>()
7272
.with::<LaserPointer>()
7373
.insert_on_init(|| SimpleSphere)
74+
.insert_on_init_during_editor(|| Vpeol3dSnapToPlane {
75+
normal: Dir3::Y,
76+
offset: 2.0,
77+
})
7478
});
7579
app.add_yoleck_auto_edit::<LaserPointer>();
7680
app.add_systems(YoleckSchedule::Populate, populate_simple_sphere);

src/vpeol.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ pub mod prelude {
3737
#[cfg(feature = "vpeol_3d")]
3838
pub use crate::vpeol_3d::{
3939
Vpeol3dCameraControl, Vpeol3dCameraMode, Vpeol3dPluginForEditor, Vpeol3dPluginForGame,
40-
Vpeol3dPosition, Vpeol3dRotation, Vpeol3dScale, Vpeol3dTranslationGizmoConfig,
41-
Vpeol3dTranslationGizmoMode, YoleckCameraChoices,
40+
Vpeol3dPosition, Vpeol3dRotation, Vpeol3dScale, Vpeol3dSnapToPlane,
41+
Vpeol3dTranslationGizmoConfig, Vpeol3dTranslationGizmoMode, YoleckCameraChoices,
4242
};
4343
}
4444

src/vpeol_3d.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,23 @@ pub fn vpeol_3d_camera_mode_selector(
10301030
#[cfg_attr(feature = "bevy_reflect", derive(bevy::reflect::Reflect))]
10311031
pub struct Vpeol3dPosition(pub Vec3);
10321032

1033+
/// Add this to an entity with [`Vpeol3dPosition`] to force it to be on a specific plane while
1034+
/// editing.
1035+
///
1036+
/// This is useful for 2D games that use 3D graphics but don't want to allow free positioning of
1037+
/// entities on all axes.
1038+
///
1039+
/// Note that this is not a [`YoleckComponent`]. Do not add it with
1040+
/// [`insert_on_init_during_editor`](YoleckEntityType::with). The best way to add it is by using
1041+
/// [`insert_on_init_during_editor`](YoleckEntityType::insert_on_init_during_editor) which also
1042+
/// allows setting the data.
1043+
#[derive(Component)]
1044+
pub struct Vpeol3dSnapToPlane {
1045+
pub normal: Dir3,
1046+
/// Offset of the plane from the origin of axes
1047+
pub offset: f32,
1048+
}
1049+
10331050
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10341051
pub enum Vpeol3dTranslationGizmoMode {
10351052
World,
@@ -1113,7 +1130,12 @@ impl CommonDragPlane {
11131130

11141131
fn vpeol_3d_edit_transform_group(
11151132
mut ui: ResMut<YoleckUi>,
1116-
position_edit: YoleckEdit<(Entity, &mut Vpeol3dPosition, Option<&VpeolDragPlane>)>,
1133+
position_edit: YoleckEdit<(
1134+
Entity,
1135+
&mut Vpeol3dPosition,
1136+
Option<&VpeolDragPlane>,
1137+
Option<&Vpeol3dSnapToPlane>,
1138+
)>,
11171139
rotation_edit: YoleckEdit<&mut Vpeol3dRotation>,
11181140
scale_edit: YoleckEdit<&mut Vpeol3dScale>,
11191141
global_drag_plane: Res<VpeolDragPlane>,
@@ -1136,7 +1158,12 @@ fn vpeol_3d_edit_transform_group(
11361158

11371159
fn vpeol_3d_edit_position_impl(
11381160
ui: &mut egui::Ui,
1139-
mut edit: YoleckEdit<(Entity, &mut Vpeol3dPosition, Option<&VpeolDragPlane>)>,
1161+
mut edit: YoleckEdit<(
1162+
Entity,
1163+
&mut Vpeol3dPosition,
1164+
Option<&VpeolDragPlane>,
1165+
Option<&Vpeol3dSnapToPlane>,
1166+
)>,
11401167
global_drag_plane: &VpeolDragPlane,
11411168
passed_data: &YoleckPassedData,
11421169
) {
@@ -1149,7 +1176,7 @@ fn vpeol_3d_edit_position_impl(
11491176

11501177
let mut common_drag_plane = CommonDragPlane::NotDecidedYet;
11511178

1152-
for (entity, position, drag_plane) in edit.iter_matching() {
1179+
for (entity, position, drag_plane, _) in edit.iter_matching() {
11531180
let VpeolDragPlane(drag_plane) = drag_plane.unwrap_or(global_drag_plane);
11541181
common_drag_plane.consider(*drag_plane.normal);
11551182

@@ -1180,8 +1207,12 @@ fn vpeol_3d_edit_position_impl(
11801207
});
11811208

11821209
if transition.is_finite() && transition != Vec3::ZERO {
1183-
for (_, mut position, _) in edit.iter_matching_mut() {
1210+
for (_, mut position, _, snap) in edit.iter_matching_mut() {
11841211
position.0 += transition;
1212+
if let Some(snap) = snap {
1213+
let displacement = position.0.project_onto(*snap.normal);
1214+
position.0 += snap.offset * snap.normal - displacement;
1215+
}
11851216
}
11861217
}
11871218
}

0 commit comments

Comments
 (0)