+ //TimeTaker tt("axisAlignedCollision");
+
+ f32 xsize = (staticbox.MaxEdge.X - staticbox.MinEdge.X) - COLL_ZERO; // reduce box size for solve collision stuck (flying sand)
+ f32 ysize = (staticbox.MaxEdge.Y - staticbox.MinEdge.Y); // - COLL_ZERO; // Y - no sense for falling, but maybe try later
+ f32 zsize = (staticbox.MaxEdge.Z - staticbox.MinEdge.Z) - COLL_ZERO;
+
+ aabb3f relbox(
+ movingbox.MinEdge.X - staticbox.MinEdge.X,
+ movingbox.MinEdge.Y - staticbox.MinEdge.Y,
+ movingbox.MinEdge.Z - staticbox.MinEdge.Z,
+ movingbox.MaxEdge.X - staticbox.MinEdge.X,
+ movingbox.MaxEdge.Y - staticbox.MinEdge.Y,
+ movingbox.MaxEdge.Z - staticbox.MinEdge.Z
+ );
+
+ if(speed.X > 0) // Check for collision with X- plane
+ {
+ if(relbox.MaxEdge.X <= d)
+ {
+ dtime = - relbox.MaxEdge.X / speed.X;
+ if((relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
+ (relbox.MaxEdge.Y + speed.Y * dtime > COLL_ZERO) &&
+ (relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
+ (relbox.MaxEdge.Z + speed.Z * dtime > COLL_ZERO))
+ return 0;
+ }
+ else if(relbox.MinEdge.X > xsize)
+ {
+ return -1;
+ }
+ }
+ else if(speed.X < 0) // Check for collision with X+ plane
+ {
+ if(relbox.MinEdge.X >= xsize - d)
+ {
+ dtime = (xsize - relbox.MinEdge.X) / speed.X;
+ if((relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
+ (relbox.MaxEdge.Y + speed.Y * dtime > COLL_ZERO) &&
+ (relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
+ (relbox.MaxEdge.Z + speed.Z * dtime > COLL_ZERO))
+ return 0;
+ }
+ else if(relbox.MaxEdge.X < 0)
+ {
+ return -1;
+ }
+ }
+
+ // NO else if here
+
+ if(speed.Y > 0) // Check for collision with Y- plane
+ {
+ if(relbox.MaxEdge.Y <= d)
+ {
+ dtime = - relbox.MaxEdge.Y / speed.Y;
+ if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
+ (relbox.MaxEdge.X + speed.X * dtime > COLL_ZERO) &&
+ (relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
+ (relbox.MaxEdge.Z + speed.Z * dtime > COLL_ZERO))
+ return 1;
+ }
+ else if(relbox.MinEdge.Y > ysize)
+ {
+ return -1;
+ }
+ }
+ else if(speed.Y < 0) // Check for collision with Y+ plane
+ {
+ if(relbox.MinEdge.Y >= ysize - d)
+ {
+ dtime = (ysize - relbox.MinEdge.Y) / speed.Y;
+ if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
+ (relbox.MaxEdge.X + speed.X * dtime > COLL_ZERO) &&
+ (relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
+ (relbox.MaxEdge.Z + speed.Z * dtime > COLL_ZERO))
+ return 1;
+ }
+ else if(relbox.MaxEdge.Y < 0)
+ {
+ return -1;
+ }
+ }
+
+ // NO else if here
+
+ if(speed.Z > 0) // Check for collision with Z- plane
+ {
+ if(relbox.MaxEdge.Z <= d)
+ {
+ dtime = - relbox.MaxEdge.Z / speed.Z;
+ if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
+ (relbox.MaxEdge.X + speed.X * dtime > COLL_ZERO) &&
+ (relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
+ (relbox.MaxEdge.Y + speed.Y * dtime > COLL_ZERO))
+ return 2;
+ }
+ //else if(relbox.MinEdge.Z > zsize)
+ //{
+ // return -1;
+ //}
+ }
+ else if(speed.Z < 0) // Check for collision with Z+ plane
+ {
+ if(relbox.MinEdge.Z >= zsize - d)
+ {
+ dtime = (zsize - relbox.MinEdge.Z) / speed.Z;
+ if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
+ (relbox.MaxEdge.X + speed.X * dtime > COLL_ZERO) &&
+ (relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
+ (relbox.MaxEdge.Y + speed.Y * dtime > COLL_ZERO))
+ return 2;
+ }
+ //else if(relbox.MaxEdge.Z < 0)
+ //{
+ // return -1;
+ //}
+ }
+
+ return -1;
+}
+
+// Helper function:
+// Checks if moving the movingbox up by the given distance would hit a ceiling.
+bool wouldCollideWithCeiling(
+ const std::vector<aabb3f> &staticboxes,
+ const aabb3f &movingbox,
+ f32 y_increase, f32 d)
+{
+ //TimeTaker tt("wouldCollideWithCeiling");
+
+ assert(y_increase >= 0);
+
+ for(std::vector<aabb3f>::const_iterator
+ i = staticboxes.begin();
+ i != staticboxes.end(); i++)
+ {
+ const aabb3f& staticbox = *i;
+ 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;
+}
+
+
+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)
+{
+ Map *map = &env->getMap();
+ //TimeTaker tt("collisionMoveSimple");
+ ScopeProfiler sp(g_profiler, "collisionMoveSimple avg", SPT_AVG);
+