Skip to content

Commit

Permalink
collision fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kno10 committed Nov 9, 2024
1 parent d23b2c8 commit 217fd70
Showing 1 changed file with 22 additions and 7 deletions.
29 changes: 22 additions & 7 deletions src/collision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ struct NearbyCollisionInfo {
position(pos),
bouncy(bouncy),
is_unloaded(is_ul),
is_step_up(false)
is_step_up(false),
has_collided(false)
{}

// object
Expand All @@ -42,17 +43,23 @@ struct NearbyCollisionInfo {
box(box),
bouncy(bouncy),
is_unloaded(false),
is_step_up(false)
is_step_up(false),
has_collided(false)
{}

inline bool isObject() const { return obj != nullptr; }

ActiveObject *obj;
aabb3f box;
v3s16 position;
f32 distance;
u8 bouncy;
// bitfield to save space
bool is_unloaded:1, is_step_up:1;
bool is_unloaded:1, is_step_up:1, has_collided:1;

bool operator<(const NearbyCollisionInfo& b) {
return distance < b.distance;
}
};

// Helper functions:
Expand Down Expand Up @@ -407,12 +414,19 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
add_object_boxes(env, box_0, dtime, *pos_f, aspeed_f, self, cinfo);
}

// Sort boxes by distance once, as we are more likely to collide with near boxes
v3f center_0 = box_0.getCenter();
for (auto box = cinfo.begin(); box != cinfo.end(); box++) {
box->distance = (box->box.getCenter() - center_0).getLengthSQ();
}
std::sort(cinfo.begin(), cinfo.end());

// Collision detection
f32 d = 0.0f;
for (int loopcount = 0;; loopcount++) {
if (loopcount >= 100) {
warningstream << "collisionMoveSimple: Loop count exceeded, aborting to avoid infinite loop" << std::endl;
g_collision_problems_encountered = true;
g_collision_problems_encountered = true; // for unit tests
break;
}

Expand All @@ -428,7 +442,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
for (u32 boxindex = 0; boxindex < cinfo.size(); boxindex++) {
const NearbyCollisionInfo &box_info = cinfo[boxindex];
// Ignore if already stepped up this nodebox.
if (box_info.is_step_up)
if (box_info.is_step_up || box_info.has_collided)
continue;

// Find nearest collision of the two boxes (raytracing-like)
Expand All @@ -454,6 +468,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
}
// Otherwise, a collision occurred.
NearbyCollisionInfo &nearest_info = cinfo[nearest_boxindex];
nearest_info.has_collided = true;
const aabb3f& cbox = nearest_info.box;

//movingbox except moved to the horizontal position it would be after step up
Expand Down Expand Up @@ -555,7 +570,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
}
result.collides = true;
} else {
is_collision = false;
is_collision = false; // unreachable, actually
}

info.new_speed = *speed_f;
Expand Down Expand Up @@ -595,7 +610,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
cbox.MaxEdge.Z - d > box.MinEdge.Z &&
cbox.MinEdge.Z + d < box.MaxEdge.Z) {
if (box_info.is_step_up) {
pos_f->Y += cbox.MaxEdge.Y - box.MinEdge.Y;
pos_f->Y += cbox.MaxEdge.Y - box.MinEdge.Y + 0.01f; // avoid glitching into the floor
box = box_0;
box.MinEdge += *pos_f;
box.MaxEdge += *pos_f;
Expand Down

0 comments on commit 217fd70

Please sign in to comment.