// Helper function: // Checks for collision of a moving aabbox with a static aabbox // Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision // The time after which the collision occurs is stored in dtime. int axisAlignedCollision( const aabb3f &staticbox, const aabb3f &movingbox, const v3f &speed, f32 d, f32 &dtime) { //TimeTaker tt("axisAlignedCollision"); f32 xsize = (staticbox.MaxEdge.X - staticbox.MinEdge.X); f32 ysize = (staticbox.MaxEdge.Y - staticbox.MinEdge.Y); f32 zsize = (staticbox.MaxEdge.Z - staticbox.MinEdge.Z); 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 > 0) && (relbox.MinEdge.Z + speed.Z * dtime < zsize) && (relbox.MaxEdge.Z + speed.Z * dtime > 0)) 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 > 0) && (relbox.MinEdge.Z + speed.Z * dtime < zsize) && (relbox.MaxEdge.Z + speed.Z * dtime > 0)) 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 > 0) && (relbox.MinEdge.Z + speed.Z * dtime < zsize) && (relbox.MaxEdge.Z + speed.Z * dtime > 0)) 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 > 0) && (relbox.MinEdge.Z + speed.Z * dtime < zsize) && (relbox.MaxEdge.Z + speed.Z * dtime > 0)) 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 > 0) && (relbox.MinEdge.Y + speed.Y * dtime < ysize) && (relbox.MaxEdge.Y + speed.Y * dtime > 0)) 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 > 0) && (relbox.MinEdge.Y + speed.Y * dtime < ysize) && (relbox.MaxEdge.Y + speed.Y * dtime > 0)) return 2; } //else if(relbox.MaxEdge.Z < 0) //{ // return -1; //} } return -1; }
// Helper function: // Checks for collision of a moving aabbox with a static aabbox // Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision // The time after which the collision occurs is stored in dtime. int axisAlignedCollision( const aabb3f &staticbox, const aabb3f &movingbox, const v3f &speed, f32 d, f32 *dtime) { //TimeTaker tt("axisAlignedCollision"); f32 xsize = (staticbox.MaxEdge.X - staticbox.MinEdge.X); // - COLL_ZEROY; // 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_ZEROY; 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 ); // These cases can (and should) be rejected immediately if( (speed.X >= 0 && relbox.MinEdge.X > xsize) || (speed.X <= 0 && relbox.MaxEdge.X < 0) || (speed.Y >= 0 && relbox.MinEdge.Y > ysize) || (speed.Y <= 0 && relbox.MaxEdge.Y < 0) || (speed.Z >= 0 && relbox.MinEdge.Z > zsize) || (speed.Z <= 0 && relbox.MaxEdge.Z < 0)) return -1; 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(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; } } // 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(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_ZEROY) && (relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) && (relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZEROY)) 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(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; } } return -1; }
// Helper function: // Checks for collision of a moving aabbox with a static aabbox // Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision // The time after which the collision occurs is stored in dtime. int axisAlignedCollision( const aabb3f &staticbox, const aabb3f &movingbox, const v3f &speed, f32 d, f32 &dtime) { //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; }