From 50d202ea82e3025ade7ef464f33417d0cb6d5caa Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sat, 30 Jan 2010 09:23:14 +0000 Subject: [PATCH] Bug 456: Avoid hurting Tux in a ravine. - Fix blooper where slope constraints overwrote previously calculated constraints. - Make static collision detection symmetrical left-right. There are still a lot of things wrong with static collision detection, which I hope to fix later. SVN-Revision: 6284 --- src/supertux/collision.cpp | 18 ++++++++---------- src/supertux/collision.hpp | 7 +++++++ src/supertux/sector.cpp | 28 ++++++++++++++++------------ 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/supertux/collision.cpp b/src/supertux/collision.cpp index 6729d0540..f3dc04168 100644 --- a/src/supertux/collision.cpp +++ b/src/supertux/collision.cpp @@ -121,21 +121,19 @@ bool rectangle_aatriangle(Constraints* constraints, const Rectf& rect, if(p1.x < area.p1.x - RDELTA || p1.x > area.p2.x + RDELTA || p1.y < area.p1.y - RDELTA || p1.y > area.p2.y + RDELTA) { set_rectangle_rectangle_constraints(constraints, rect, area); - constraints->hit.left = false; - constraints->hit.right = false; } else { if(outvec.x < 0) { - constraints->right = rect.get_right() + outvec.x; + constraints->min_right(rect.get_right() + outvec.x); } else { - constraints->left = rect.get_left() + outvec.x; + constraints->max_left(rect.get_left() + outvec.x); } if(outvec.y < 0) { - constraints->bottom = rect.get_bottom() + outvec.y; + constraints->min_bottom(rect.get_bottom() + outvec.y); constraints->hit.bottom = true; constraints->ground_movement += addl_ground_movement; } else { - constraints->top = rect.get_top() + outvec.y; + constraints->max_top(rect.get_top() + outvec.y); constraints->hit.top = true; } constraints->hit.slope_normal = normal; @@ -156,19 +154,19 @@ void set_rectangle_rectangle_constraints(Constraints* constraints, float horiz_penetration = std::min(ileft, iright); if(vert_penetration < horiz_penetration) { if(itop < ibottom) { - constraints->bottom = std::min(constraints->bottom, r2.get_top()); + constraints->min_bottom(r2.get_top()); constraints->hit.bottom = true; constraints->ground_movement += addl_ground_movement; } else { - constraints->top = std::max(constraints->top, r2.get_bottom()); + constraints->max_top(r2.get_bottom()); constraints->hit.top = true; } } else { if(ileft < iright) { - constraints->right = std::min(constraints->right, r2.get_left()); + constraints->min_right(r2.get_left()); constraints->hit.right = true; } else { - constraints->left = std::max(constraints->left, r2.get_right()); + constraints->max_left(r2.get_right()); constraints->hit.left = true; } } diff --git a/src/supertux/collision.hpp b/src/supertux/collision.hpp index a500a2b1e..14d15b0dc 100644 --- a/src/supertux/collision.hpp +++ b/src/supertux/collision.hpp @@ -19,6 +19,7 @@ #include "supertux/collision_hit.hpp" #include +#include /* min/max */ class Vector; class Rectf; @@ -63,6 +64,12 @@ public: float right; float top; float bottom; + + void max_left (float left2 ) { left = std::max(left , left2 ); } + void min_right (float right2 ) { right = std::min(right , right2 ); } + void max_top (float top2 ) { top = std::max(top , top2 ); } + void min_bottom(float bottom2) { bottom = std::min(bottom, bottom2); } + Vector ground_movement; CollisionHit hit; }; diff --git a/src/supertux/sector.cpp b/src/supertux/sector.cpp index d337fc8e7..2cbbeb919 100644 --- a/src/supertux/sector.cpp +++ b/src/supertux/sector.cpp @@ -902,19 +902,19 @@ void check_collisions(collision::Constraints* constraints, if(fabsf(movement.y) > fabsf(movement.x)) { if(ileft < SHIFT_DELTA) { - constraints->right = std::min(constraints->right, r2.get_left()); + constraints->min_right(r2.get_left()); return; } else if(iright < SHIFT_DELTA) { - constraints->left = std::max(constraints->left, r2.get_right()); + constraints->max_left(r2.get_right()); return; } } else { // shiftout bottom/top if(itop < SHIFT_DELTA) { - constraints->bottom = std::min(constraints->bottom, r2.get_top()); + constraints->min_bottom(r2.get_top()); return; } else if(ibottom < SHIFT_DELTA) { - constraints->top = std::max(constraints->top, r2.get_bottom()); + constraints->max_top(r2.get_bottom()); return; } } @@ -935,18 +935,18 @@ void check_collisions(collision::Constraints* constraints, float horiz_penetration = std::min(ileft, iright); if(vert_penetration < horiz_penetration) { if(itop < ibottom) { - constraints->bottom = std::min(constraints->bottom, r2.get_top()); + constraints->min_bottom(r2.get_top()); constraints->hit.bottom = true; } else { - constraints->top = std::max(constraints->top, r2.get_bottom()); + constraints->max_top(r2.get_bottom()); constraints->hit.top = true; } } else { if(ileft < iright) { - constraints->right = std::min(constraints->right, r2.get_left()); + constraints->min_right(r2.get_left()); constraints->hit.right = true; } else { - constraints->left = std::max(constraints->left, r2.get_right()); + constraints->max_left(r2.get_right()); constraints->hit.left = true; } } @@ -1184,8 +1184,8 @@ Sector::collision_static_constrains(MovingObject& object) break; // apply calculated vertical constraints - if(constraints.right < infinity) { - float width = constraints.right - constraints.left; + float width = constraints.right - constraints.left; + if(width < infinity) { if(width + SHIFT_DELTA < owidth) { #if 0 printf("Object %p crushed horizontally... L:%f R:%f\n", &object, @@ -1197,9 +1197,13 @@ Sector::collision_static_constrains(MovingObject& object) h.crush = true; object.collision_solid(h); } else { - dest.p2.x = constraints.right - DELTA; - dest.p1.x = dest.p2.x - owidth; + float xmid = (constraints.left + constraints.right) / 2; + dest.p1.x = xmid - owidth/2; + dest.p2.x = xmid + owidth/2; } + } else if(constraints.right < infinity) { + dest.p2.x = constraints.right - DELTA; + dest.p1.x = dest.p2.x - owidth; } else if(constraints.left > -infinity) { dest.p1.x = constraints.left + DELTA; dest.p2.x = dest.p1.x + owidth; -- 2.11.0