~starkingdoms/starkingdoms

dc538d5f9aeb7635278cf40d12df489ef59419a2 — ghostly_zsh 28 days ago de4eacb
feat: spring-like ghost tracking
1 files changed, 11 insertions(+), 5 deletions(-)

M crates/unified/src/client/parts.rs
M crates/unified/src/client/parts.rs => crates/unified/src/client/parts.rs +11 -5
@@ 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;