+ const f32 dtime_max = *dtime;
+ f32 inner_margin; // the distance of clipping recovery
+ f32 distance;
+ f32 time;
+
+
+ if (speed.Y) {
+ distance = relbox.MaxEdge.Y - relbox.MinEdge.Y;
+ *dtime = distance / std::abs(speed.Y);
+ time = std::max(*dtime, 0.0f);
+
+ if (*dtime <= dtime_max) {
+ inner_margin = std::max(-0.5f * (staticbox.MaxEdge.Y - staticbox.MinEdge.Y), -2.0f);
+
+ if ((speed.Y > 0 && staticbox.MinEdge.Y - movingbox.MaxEdge.Y > inner_margin) ||
+ (speed.Y < 0 && movingbox.MinEdge.Y - staticbox.MaxEdge.Y > inner_margin)) {
+ if (
+ (std::max(movingbox.MaxEdge.X + speed.X * time, staticbox.MaxEdge.X)
+ - std::min(movingbox.MinEdge.X + speed.X * time, staticbox.MinEdge.X)
+ - relbox.MinEdge.X < 0) &&
+ (std::max(movingbox.MaxEdge.Z + speed.Z * time, staticbox.MaxEdge.Z)
+ - std::min(movingbox.MinEdge.Z + speed.Z * time, staticbox.MinEdge.Z)
+ - relbox.MinEdge.Z < 0)
+ )
+ return COLLISION_AXIS_Y;
+ }
+ }
+ else {
+ return COLLISION_AXIS_NONE;
+ }
+ }
+
+ // NO else if here
+
+ if (speed.X) {
+ distance = relbox.MaxEdge.X - relbox.MinEdge.X;
+ *dtime = distance / std::abs(speed.X);
+ time = std::max(*dtime, 0.0f);
+
+ if (*dtime <= dtime_max) {
+ inner_margin = std::max(-0.5f * (staticbox.MaxEdge.X - staticbox.MinEdge.X), -2.0f);
+
+ if ((speed.X > 0 && staticbox.MinEdge.X - movingbox.MaxEdge.X > inner_margin) ||
+ (speed.X < 0 && movingbox.MinEdge.X - staticbox.MaxEdge.X > inner_margin)) {
+ if (
+ (std::max(movingbox.MaxEdge.Y + speed.Y * time, staticbox.MaxEdge.Y)
+ - std::min(movingbox.MinEdge.Y + speed.Y * time, staticbox.MinEdge.Y)
+ - relbox.MinEdge.Y < 0) &&
+ (std::max(movingbox.MaxEdge.Z + speed.Z * time, staticbox.MaxEdge.Z)
+ - std::min(movingbox.MinEdge.Z + speed.Z * time, staticbox.MinEdge.Z)
+ - relbox.MinEdge.Z < 0)
+ )
+ return COLLISION_AXIS_X;
+ }
+ } else {
+ return COLLISION_AXIS_NONE;
+ }
+ }
+
+ // NO else if here
+
+ if (speed.Z) {
+ distance = relbox.MaxEdge.Z - relbox.MinEdge.Z;
+ *dtime = distance / std::abs(speed.Z);
+ time = std::max(*dtime, 0.0f);
+
+ if (*dtime <= dtime_max) {
+ inner_margin = std::max(-0.5f * (staticbox.MaxEdge.Z - staticbox.MinEdge.Z), -2.0f);
+
+ if ((speed.Z > 0 && staticbox.MinEdge.Z - movingbox.MaxEdge.Z > inner_margin) ||
+ (speed.Z < 0 && movingbox.MinEdge.Z - staticbox.MaxEdge.Z > inner_margin)) {
+ if (
+ (std::max(movingbox.MaxEdge.X + speed.X * time, staticbox.MaxEdge.X)
+ - std::min(movingbox.MinEdge.X + speed.X * time, staticbox.MinEdge.X)
+ - relbox.MinEdge.X < 0) &&
+ (std::max(movingbox.MaxEdge.Y + speed.Y * time, staticbox.MaxEdge.Y)
+ - std::min(movingbox.MinEdge.Y + speed.Y * time, staticbox.MinEdge.Y)
+ - relbox.MinEdge.Y < 0)
+ )
+ return COLLISION_AXIS_Z;
+ }
+ }
+ }
+
+ return COLLISION_AXIS_NONE;
+}
+
+// Helper function:
+// Checks if moving the movingbox up by the given distance would hit a ceiling.
+bool wouldCollideWithCeiling(
+ const std::vector<NearbyCollisionInfo> &cinfo,
+ const aabb3f &movingbox,
+ f32 y_increase, f32 d)
+{
+ //TimeTaker tt("wouldCollideWithCeiling");
+
+ assert(y_increase >= 0); // pre-condition
+
+ for (const auto &it : cinfo) {
+ const aabb3f &staticbox = it.box;
+ if ((movingbox.MaxEdge.Y - d <= staticbox.MinEdge.Y) &&
+ (movingbox.MaxEdge.Y + y_increase > staticbox.MinEdge.Y) &&
+ (movingbox.MinEdge.X < staticbox.MaxEdge.X) &&
+ (movingbox.MaxEdge.X > staticbox.MinEdge.X) &&
+ (movingbox.MinEdge.Z < staticbox.MaxEdge.Z) &&
+ (movingbox.MaxEdge.Z > staticbox.MinEdge.Z))
+ return true;
+ }
+
+ return false;
+}
+
+static inline void getNeighborConnectingFace(const v3s16 &p,
+ const NodeDefManager *nodedef, Map *map, MapNode n, int v, int *neighbors)
+{
+ MapNode n2 = map->getNode(p);
+ if (nodedef->nodeboxConnects(n, n2, v))
+ *neighbors |= v;
+}
+
+collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
+ f32 pos_max_d, const aabb3f &box_0,
+ f32 stepheight, f32 dtime,
+ v3f *pos_f, v3f *speed_f,
+ v3f accel_f, ActiveObject *self,
+ bool collideWithObjects, bool jesus)
+{
+ static bool time_notification_done = false;
+ Map *map = &env->getMap();
+
+ ScopeProfiler sp(g_profiler, "collisionMoveSimple()", SPT_AVG);
+
+ collisionMoveResult result;