Fix jumping at node edge
authorgregorycu <gregory.currie@gmail.com>
Tue, 27 Jan 2015 12:33:54 +0000 (23:33 +1100)
committerShadowNinja <shadowninja@minetest.net>
Sat, 20 Feb 2016 01:05:58 +0000 (20:05 -0500)
src/collision.cpp

index 2ae59b38f17c62cc127b990272d08adb57f9c66c..a2d17d51ab50b554884ffb112807e084a4cb76ed 100644 (file)
@@ -248,8 +248,9 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
 
        bool any_position_valid = false;
 
+       // The order is important here, must be y first
+       for(s16 y = max_y; y >= min_y; y--)
        for(s16 x = min_x; x <= max_x; x++)
-       for(s16 y = min_y; y <= max_y; y++)
        for(s16 z = min_z; z <= max_z; z++)
        {
                v3s16 p(x,y,z);
@@ -404,15 +405,17 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                        Go through every nodebox, find nearest collision
                */
                for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) {
-                       // Ignore if already stepped up this nodebox.
-                       if(is_step_up[boxindex])
-                               continue;
-
                        // Find nearest collision of the two boxes (raytracing-like)
                        f32 dtime_tmp;
                        int collided = axisAlignedCollision(
                                        cboxes[boxindex], movingbox, *speed_f, d, &dtime_tmp);
 
+                       // Ignore if already stepped up this nodebox.
+                       if (is_step_up[boxindex]) {
+                               pos_f->Y += (cboxes[boxindex].MaxEdge.Y - movingbox.MinEdge.Y);
+                               continue;
+                       }
+
                        if (collided == -1 || dtime_tmp >= nearest_dtime)
                                continue;
 
@@ -462,10 +465,12 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                                is_collision = false;
 
                        CollisionInfo info;
-                       if (is_object[nearest_boxindex])
+                       if (is_object[nearest_boxindex]) {
                                info.type = COLLISION_OBJECT;
-                       else
+                               result.standing_on_object = true;
+                       } else {
                                info.type = COLLISION_NODE;
+                       }
 
                        info.node_p = node_positions[nearest_boxindex];
                        info.bouncy = bouncy;
@@ -483,12 +488,13 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                                        speed_f->X = 0;
                                result.collides = true;
                                result.collides_xz = true;
-                       }
-                       else if(nearest_collided == 1) { // Y
-                               if (fabs(speed_f->Y) > BS * 3)
+                       } else if(nearest_collided == 1) { // Y
+                               if (fabs(speed_f->Y) > BS * 3) {
                                        speed_f->Y *= bounce;
-                               else
+                               } else {
                                        speed_f->Y = 0;
+                                       result.touching_ground = true;
+                               }
                                result.collides = true;
                        } else if(nearest_collided == 2) { // Z
                                if (fabs(speed_f->Z) > BS * 3)
@@ -509,43 +515,5 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                }
        }
 
-       /*
-               Final touches: Check if standing on ground, step up stairs.
-       */
-       aabb3f box = box_0;
-       box.MinEdge += *pos_f;
-       box.MaxEdge += *pos_f;
-       for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) {
-               const aabb3f& cbox = cboxes[boxindex];
-
-               /*
-                       See if the object is touching ground.
-
-                       Object touches ground if object's minimum Y is near node's
-                       maximum Y and object's X-Z-area overlaps with the node's
-                       X-Z-area.
-
-                       Use 0.15*BS so that it is easier to get on a node.
-               */
-               if (cbox.MaxEdge.X - d > box.MinEdge.X && cbox.MinEdge.X + d < box.MaxEdge.X &&
-                               cbox.MaxEdge.Z - d > box.MinEdge.Z &&
-                               cbox.MinEdge.Z + d < box.MaxEdge.Z) {
-                       if (is_step_up[boxindex]) {
-                               pos_f->Y += (cbox.MaxEdge.Y - box.MinEdge.Y);
-                               box = box_0;
-                               box.MinEdge += *pos_f;
-                               box.MaxEdge += *pos_f;
-                       }
-                       if (fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.15 * BS) {
-                               result.touching_ground = true;
-
-                               if (is_object[boxindex])
-                                       result.standing_on_object = true;
-                               if (is_unloaded[boxindex])
-                                       result.standing_on_unloaded = true;
-                       }
-               }
-       }
-
        return result;
 }