| 850 | } |
| 851 | |
| 852 | MovementController::CollisionResult MovementController::collisionMove(List<CollisionPoly>& collisionPolys, PolyF const& body, Vec2F const& movement, |
| 853 | bool ignorePlatforms, bool enableSurfaceSlopeCorrection, float maximumCorrection, float maximumPlatformCorrection, Vec2F sortCenter, float dt) { |
| 854 | unsigned const MaximumSeparationLoops = 3; |
| 855 | float const SlideAngle = Constants::pi / 3; |
| 856 | float const SlideCorrectionLimit = 0.2f; |
| 857 | float separationTolerance = 0.001f * (dt * 60.f); |
| 858 | maximumPlatformCorrection *= (dt * 60.f); |
| 859 | |
| 860 | if (body.isNull()) |
| 861 | return {movement, Vec2F(), {}, false, false, Vec2F(1, 0), CollisionKind::None}; |
| 862 | |
| 863 | PolyF translatedBody = body; |
| 864 | translatedBody.translate(movement); |
| 865 | PolyF checkBody = translatedBody; |
| 866 | Vec2F totalCorrection = Vec2F(); |
| 867 | CollisionKind maxCollided = CollisionKind::None; |
| 868 | Maybe<MovingCollisionId> surfaceMovingCollisionId; |
| 869 | |
| 870 | CollisionSeparation separation = {}; |
| 871 | |
| 872 | if (enableSurfaceSlopeCorrection) { |
| 873 | // First try separating with our ground sliding cheat. |
| 874 | separation = collisionSeparate(collisionPolys, checkBody, ignorePlatforms, maximumPlatformCorrection, sortCenter, true, separationTolerance); |
| 875 | totalCorrection += separation.correction; |
| 876 | checkBody.translate(separation.correction); |
| 877 | maxCollided = maxOrNullCollision(maxCollided, separation.collisionKind); |
| 878 | surfaceMovingCollisionId = separation.movingCollisionId; |
| 879 | Vec2F upwardResult = movement + separation.correction; |
| 880 | float upMag = upwardResult.magnitude(); |
| 881 | // Angle off of horizontal (minimum of either direction) |
| 882 | float angleHoriz = std::min(Vec2F(1, 0).angleBetweenNormalized(upwardResult / upMag), |
| 883 | Vec2F(-1, 0).angleBetweenNormalized(upwardResult / upMag)); |
| 884 | |
| 885 | // We need to make sure that even if we found a solution with the sliding |
| 886 | // cheat, we are not beyond the angle and correction limits for the ground |
| 887 | // cheat correction. |
| 888 | if (separation.solutionFound) |
| 889 | separation.solutionFound = upMag < SlideCorrectionLimit || angleHoriz < SlideAngle; |
| 890 | |
| 891 | if (separation.solutionFound) { |
| 892 | if (totalCorrection.magnitude() > maximumCorrection) |
| 893 | separation.solutionFound = false; |
| 894 | } |
| 895 | } |
| 896 | |
| 897 | if (!separation.solutionFound) { |
| 898 | checkBody = translatedBody; |
| 899 | totalCorrection = Vec2F(); |
| 900 | for (size_t i = 0; i < MaximumSeparationLoops; ++i) { |
| 901 | separation = collisionSeparate(collisionPolys, checkBody, ignorePlatforms, |
| 902 | maximumPlatformCorrection, sortCenter, false, separationTolerance); |
| 903 | totalCorrection += separation.correction; |
| 904 | checkBody.translate(separation.correction); |
| 905 | maxCollided = maxOrNullCollision(maxCollided, separation.collisionKind); |
| 906 | surfaceMovingCollisionId = {}; |
| 907 | |
| 908 | if (totalCorrection.magnitude() > maximumCorrection) { |
| 909 | separation.solutionFound = false; |
nothing calls this directly
no test coverage detected