@@ 116,6 116,8 @@ struct SnapResource(Option<Entity>, Option<Entity>);
struct DragGhost;
#[derive(Component)]
struct GhostTarget(pub Quat);
+#[derive(Component)]
+struct GhostVelocity(pub Vec3);
const TRANSLATION_SMOOTH: f32 = 0.3;
const ROTATION_SMOOTH: f32 = 0.1;
@@ 145,7 147,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, GhostTarget(sprite.1.rotation), *sprite.1, s));
+ commands.spawn((DragGhost, GhostVelocity(Vec3::ZERO), GhostTarget(sprite.1.rotation), *sprite.1, s));
drag.0 = Some(ev.event().event_target());
}
@@ 189,7 191,7 @@ fn on_part_release(
/// This code is super cursed, and it will break at the lightest breeze
fn update_drag_ghosts(
ghost: Single<
- (&mut Transform, &mut GhostTarget),
+ (&mut Transform, &mut GhostVelocity, &mut GhostTarget),
(
With<DragGhost>,
Without<SnapOf>,
@@ 211,7 213,7 @@ fn update_drag_ghosts(
) {
const CUTOFF: f32 = 25.0; // px
- let (mut ghost, mut ghost_target) = ghost.into_inner();
+ let (mut ghost, mut ghost_velocity, mut ghost_target) = ghost.into_inner();
let Some(cursor) = cursor.0 else { return };
let mut best_distance = f32::INFINITY;
@@ 345,8 347,12 @@ fn update_drag_ghosts(
}
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;
+ let disp = ghost.translation - best_target.translation;
+ const K: f32 = 0.07;
+ const C: f32 = 0.5;
+ let a = (-K*disp - C*ghost_velocity.0)/2.0;
+ ghost.translation += ghost_velocity.0;
+ ghost_velocity.0 += a;
rsnap.0 = snap;
rsnap.1 = best_self_snap;