From 47a43d054425d91e06a543794ae4b80e6e0a96d2 Mon Sep 17 00:00:00 2001 From: JugadorXEI Date: Tue, 12 Aug 2025 14:50:43 +0200 Subject: [PATCH] Fix loops so that they work in all directions --- src/objects/loops.cpp | 85 +++---------------------------------------- src/p_loop.c | 14 +++---- 2 files changed, 11 insertions(+), 88 deletions(-) diff --git a/src/objects/loops.cpp b/src/objects/loops.cpp index ddb401891..cb512d396 100644 --- a/src/objects/loops.cpp +++ b/src/objects/loops.cpp @@ -151,81 +151,6 @@ get_binary_direction } } -static std::optional -intersect -( const mobj_t * anchor, - const mobj_t * toucher) -{ - struct Line - { - angle_t a; - vector2_t o; - - angle_t k = AbsAngle(a); - - Line(vector2_t o_, angle_t a_) : a(a_), o(o_) {} - - bool vertical() const { return k == ANGLE_90; } - - fixed_t m() const - { - // tangent table is offset 90 degrees - return FTAN(a - ANGLE_90); - } - - fixed_t b() const - { - return o.y - FixedMul(o.x, m()); - } - - fixed_t y(fixed_t x) const - { - return FixedMul(m(), x) + b(); - } - }; - - if (toucher->momx == 0 && toucher->momy == 0) - { - // undefined angle - return {}; - } - - Line a({toucher->x, toucher->y}, - R_PointToAngle2(0, 0, toucher->momx, toucher->momy)); - - Line b({anchor->x, anchor->y}, anchor->angle + ANGLE_90); - - if (a.k == b.k) - { - // parallel lines do not intersect - return {}; - } - - vector2_t v; - - auto v_intersect = [&v](Line &a, Line &b) - { - if (a.vertical()) - { - return false; - } - - v.x = b.o.x; - v.y = a.y(v.x); - - return true; - }; - - if (!v_intersect(a, b) && !v_intersect(b, a)) - { - // untested! - v.x = FixedDiv(a.b() - b.b(), b.m() - a.m()); - v.y = a.y(v.x); - } - - return v; -} - mobj_t * Obj_FindLoopCenter (const mtag_t tag) { @@ -330,10 +255,12 @@ Obj_LoopEndpointCollide { set_shiftxy(player, anchor); - vector2_t i = intersect(anchor, toucher) - .value_or(vector2_t {px, py}); - - s->origin_shift = {i.x - px, i.y - py}; + const fixed_t magnitude = R_PointToDist2(0, 0, px, py); + const fixed_t newX = FixedDiv(px, magnitude); + const fixed_t newY = FixedDiv(py, magnitude); + + s->origin_shift = {FixedMul(newX, FCOS(anchor->angle)), + FixedMul(newY, FSIN(anchor->angle))}; } flip = get_binary_direction(pitch, toucher); diff --git a/src/p_loop.c b/src/p_loop.c index 9ddf22f7b..93ef4c060 100644 --- a/src/p_loop.c +++ b/src/p_loop.c @@ -101,7 +101,7 @@ boolean P_PlayerOrbit(player_t *player) fixed_t r, xy, z; fixed_t xs, ys; - fixed_t step, th, left; + fixed_t step, left; fixed_t grav; @@ -136,16 +136,12 @@ boolean P_PlayerOrbit(player_t *player) // XY shift is transformed on wave scale; less movement // at start and end of rotation, more halfway. - th = FSIN(pitch_normal - ANGLE_90); - - xs = FixedMul(s->shift.x, th); - ys = FixedMul(s->shift.y, th); + xs = FixedMul(s->shift.x, FCOS(pitch_normal)); + ys = FixedMul(s->shift.y, FSIN(pitch_normal - ANGLE_90)); // Interpolate 0-1 over entire rotation. - th = FSIN(pitch_normal / 2); - - xs += FixedMul(s->origin_shift.x, th); - ys += FixedMul(s->origin_shift.y, th); + xs += FixedMul(s->origin_shift.x, FCOS(pitch_normal)); + ys += FixedMul(s->origin_shift.y, FSIN(pitch_normal - ANGLE_90)); xs += FixedMul(xy, FCOS(s->yaw)); ys += FixedMul(xy, FSIN(s->yaw));