void Sector::collision_static_constrains(MovingObject& object) { using namespace collision; float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max()); Constraints constraints; Vector movement = object.get_movement(); Rect& dest = object.dest; float owidth = object.get_bbox().get_width(); float oheight = object.get_bbox().get_height(); for(int i = 0; i < 2; ++i) { collision_static(&constraints, Vector(0, movement.y), dest, object); if(!constraints.has_constraints()) break; // apply calculated horizontal constraints if(constraints.bottom < infinity) { float height = constraints.bottom - constraints.top; if(height < oheight) { // we're crushed, but ignore this for now, we'll get this again // later if we're really crushed or things will solve itself when // looking at the vertical constraints } dest.p2.y = constraints.bottom - DELTA; dest.p1.y = dest.p2.y - oheight; } else if(constraints.top > -infinity) { dest.p1.y = constraints.top + DELTA; dest.p2.y = dest.p1.y + oheight; } } if(constraints.has_constraints()) { if(constraints.hit.bottom) { dest.move(constraints.ground_movement); } if(constraints.hit.top || constraints.hit.bottom) { constraints.hit.left = false; constraints.hit.right = false; object.collision_solid(constraints.hit); } } constraints = Constraints(); for(int i = 0; i < 2; ++i) { collision_static(&constraints, movement, dest, object); if(!constraints.has_constraints()) break; // apply calculated vertical constraints if(constraints.right < infinity) { float width = constraints.right - constraints.left; if(width + SHIFT_DELTA < owidth) { printf("Object %p crushed horizontally... L:%f R:%f\n", &object, constraints.left, constraints.right); CollisionHit h; h.left = true; h.right = true; h.crush = true; object.collision_solid(h); } else { 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; } } if(constraints.has_constraints()) { if( constraints.hit.left || constraints.hit.right || constraints.hit.top || constraints.hit.bottom || constraints.hit.crush ) object.collision_solid(constraints.hit); } // an extra pass to make sure we're not crushed horizontally constraints = Constraints(); collision_static(&constraints, movement, dest, object); if(constraints.bottom < infinity) { float height = constraints.bottom - constraints.top; if(height + SHIFT_DELTA < oheight) { printf("Object %p crushed vertically...\n", &object); CollisionHit h; h.top = true; h.bottom = true; h.crush = true; object.collision_solid(h); } } }
void Sector::collision_static_constrains(MovingObject& object) { using namespace collision; float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max()); Constraints constraints; Vector movement = object.get_movement(); Vector pressure = Vector(0,0); Rectf& dest = object.dest; for(int i = 0; i < 2; ++i) { collision_static(&constraints, Vector(0, movement.y), dest, object); if(!constraints.has_constraints()) break; // apply calculated horizontal constraints if(constraints.get_position_bottom() < infinity) { float height = constraints.get_height (); if(height < object.get_bbox().get_height()) { // we're crushed, but ignore this for now, we'll get this again // later if we're really crushed or things will solve itself when // looking at the vertical constraints pressure.y += object.get_bbox().get_height() - height; } else { dest.p2.y = constraints.get_position_bottom() - DELTA; dest.p1.y = dest.p2.y - object.get_bbox().get_height(); } } else if(constraints.get_position_top() > -infinity) { dest.p1.y = constraints.get_position_top() + DELTA; dest.p2.y = dest.p1.y + object.get_bbox().get_height(); } } if(constraints.has_constraints()) { if(constraints.hit.bottom) { dest.move(constraints.ground_movement); } if(constraints.hit.top || constraints.hit.bottom) { constraints.hit.left = false; constraints.hit.right = false; object.collision_solid(constraints.hit); } } constraints = Constraints(); for(int i = 0; i < 2; ++i) { collision_static(&constraints, movement, dest, object); if(!constraints.has_constraints()) break; // apply calculated vertical constraints float width = constraints.get_width (); if(width < infinity) { if(width + SHIFT_DELTA < object.get_bbox().get_width()) { // we're crushed, but ignore this for now, we'll get this again // later if we're really crushed or things will solve itself when // looking at the horizontal constraints pressure.x += object.get_bbox().get_width() - width; } else { float xmid = constraints.get_x_midpoint (); dest.p1.x = xmid - object.get_bbox().get_width()/2; dest.p2.x = xmid + object.get_bbox().get_width()/2; } } else if(constraints.get_position_right() < infinity) { dest.p2.x = constraints.get_position_right() - DELTA; dest.p1.x = dest.p2.x - object.get_bbox().get_width(); } else if(constraints.get_position_left() > -infinity) { dest.p1.x = constraints.get_position_left() + DELTA; dest.p2.x = dest.p1.x + object.get_bbox().get_width(); } } if(constraints.has_constraints()) { if( constraints.hit.left || constraints.hit.right || constraints.hit.top || constraints.hit.bottom || constraints.hit.crush ) object.collision_solid(constraints.hit); } // an extra pass to make sure we're not crushed vertically if (pressure.y > 0) { constraints = Constraints(); collision_static(&constraints, movement, dest, object); if(constraints.get_position_bottom() < infinity) { float height = constraints.get_height (); if(height + SHIFT_DELTA < object.get_bbox().get_height()) { CollisionHit h; h.top = true; h.bottom = true; h.crush = pressure.y > 16; object.collision_solid(h); } } } // an extra pass to make sure we're not crushed horizontally if (pressure.x > 0) { constraints = Constraints(); collision_static(&constraints, movement, dest, object); if(constraints.get_position_right() < infinity) { float width = constraints.get_width (); if(width + SHIFT_DELTA < object.get_bbox().get_width()) { CollisionHit h; h.top = true; h.bottom = true; h.left = true; h.right = true; h.crush = pressure.x > 16; object.collision_solid(h); } } } }