@@ 81,6 81,11 @@ struct SnapResource(Option<Entity>);
#[derive(Component)]
struct DragGhost;
+#[derive(Component)]
+struct GhostTarget(pub Quat);
+
+const TRANSLATION_SMOOTH: f32 = 0.3;
+const ROTATION_SMOOTH: f32 = 0.1;
fn on_part_click(
ev: Trigger<Pointer<Pressed>>,
@@ 96,7 101,7 @@ fn on_part_click(
};
let mut s = sprite.0.clone();
s.color = Color::srgba(0.7, 0.7, 0.7, 1.0);
- commands.spawn((DragGhost, *sprite.1, s));
+ commands.spawn((DragGhost, GhostTarget(sprite.1.rotation), *sprite.1, s));
drag.0 = Some(ev.target());
}
@@ 139,7 144,7 @@ fn on_part_release(
/// This code is super cursed, and it will break at the lightest breeze
fn update_drag_ghosts(
mut ghost: Single<
- &mut Transform,
+ (&mut Transform, &mut GhostTarget),
(
With<DragGhost>,
Without<SnapOf>,
@@ 161,11 166,12 @@ fn update_drag_ghosts(
) {
const CUTOFF: f32 = 25.0; // px
+ let (mut ghost, mut ghost_target) = ghost.into_inner();
let Some(cursor) = cursor.0 else { return };
let mut best_distance = f32::INFINITY;
let mut best_target = Transform::from_xyz(cursor.x, cursor.y, 0.0);
- best_target.rotation = ghost.rotation;
+ best_target.rotation = ghost_target.0;
let mut snap = None;
for (snap_local_transform, snap_joint, snap_part, snap_id) in &snaps {
@@ 219,7 225,7 @@ fn update_drag_ghosts(
let target_transform = Transform {
translation: joint_target,
- rotation: ghost.rotation,
+ rotation: ghost_target.0,
scale: offset.scale,
};
best_distance = distance_to_cursor;
@@ 228,18 234,21 @@ fn update_drag_ghosts(
snap = Some(snap_id);
}
- **ghost = best_target;
if keys.pressed(KeyCode::KeyQ) {
- ghost.rotation = ghost.rotation.mul_quat(Quat::from_rotation_z(
+ best_target.rotation = best_target.rotation.mul_quat(Quat::from_rotation_z(
180.0_f32.to_radians() * time.delta_secs(),
));
}
if keys.pressed(KeyCode::KeyE) {
- ghost.rotation = ghost.rotation.mul_quat(Quat::from_rotation_z(
+ best_target.rotation = best_target.rotation.mul_quat(Quat::from_rotation_z(
-180.0_f32.to_radians() * time.delta_secs(),
));
}
+ ghost_target.0 = best_target.rotation;
+ ghost.rotation = ghost.rotation.slerp(ghost_target.0, ROTATION_SMOOTH);
+ let dx = TRANSLATION_SMOOTH*(best_target.translation - ghost.translation);
+ ghost.translation += dx;
rsnap.0 = snap;
}