/// <summary> /// Returns a new y coordinate that's ensured to be outside this cuboid. Used for collision detection. /// </summary> public double pushOutY(Cuboidf from, float y, ref EnumPushDirection direction) { direction = EnumPushDirection.None; if (from.X2 > X1 && from.X1 < X2 && from.Z2 > Z1 && from.Z1 < Z2) { if (y > 0.0D && from.Y2 <= Y1 && Y1 - from.Y2 < y) { direction = EnumPushDirection.Positive; y = Y1 - from.Y2; } else if (y < 0.0D && from.Y1 >= Y2 && Y2 - from.Y1 > y) { direction = EnumPushDirection.Negative; y = Y2 - from.Y1; } } return(y); }
/// <summary> /// Returns a new z coordinate that's ensured to be outside this cuboid. Used for collision detection. /// </summary> public double pushOutZ(Cuboidf from, float z, ref EnumPushDirection direction) { direction = EnumPushDirection.None; if (from.X2 > X1 && from.X1 < X2 && from.Y2 > Y1 && from.Y1 < Y2) { if (z > 0.0D && from.Z2 <= Z1 && Z1 - from.Z2 < z) { direction = EnumPushDirection.Positive; z = Z1 - from.Z2; } else if (z < 0.0D && from.Z1 >= Z2 && Z2 - from.Z1 > z) { direction = EnumPushDirection.Negative; z = Z2 - from.Z1; } } return(z); }
/// <summary> /// Returns a new x coordinate that's ensured to be outside this cuboid. Used for collision detection. /// </summary> public double pushOutX(Cuboidf from, float x, ref EnumPushDirection direction) { direction = EnumPushDirection.None; if (from.Y2 > Y1 && from.Y1 < Y2 && from.Z2 > Z1 && from.Z1 < Z2) { if (x > 0.0D && from.X2 <= X1 && X1 - from.X2 < x) { direction = EnumPushDirection.Positive; x = X1 - from.X2; } else if (x < 0.0D && from.X1 >= X2 && X2 - from.X1 > x) { direction = EnumPushDirection.Negative; x = X2 - from.X1; } } return(x); }
/// <summary> /// Returns a new z coordinate that's ensured to be outside this cuboid. Used for collision detection. /// </summary> public double pushOutZ(Cuboidd from, double motz, ref EnumPushDirection direction) { direction = EnumPushDirection.None; if (from.X2 > X1 && from.X1 < X2 && from.Y2 > Y1 && from.Y1 < Y2) { if (motz > 0.0D && from.Z2 <= Z1 && Z1 - from.Z2 < motz) { direction = EnumPushDirection.Positive; motz = Z1 - from.Z2; } else if (motz < 0.0D && from.Z1 >= Z2 && Z2 - from.Z1 > motz) { direction = EnumPushDirection.Negative; motz = Z2 - from.Z1; } } return(motz); }
/// <summary> /// Returns a new y coordinate that's ensured to be outside this cuboid. Used for collision detection. /// </summary> public double pushOutY(Cuboidd from, double moty, ref EnumPushDirection direction) { direction = EnumPushDirection.None; if (from.X2 > X1 && from.X1 < X2 && from.Z2 > Z1 && from.Z1 < Z2) { if (moty > 0.0D && from.Y2 <= Y1 && Y1 - from.Y2 < moty) { direction = EnumPushDirection.Positive; moty = Y1 - from.Y2; } else if (moty < 0.0D && from.Y1 >= Y2 && Y2 - from.Y1 > moty) { direction = EnumPushDirection.Negative; moty = Y2 - from.Y1; } } return(moty); }
/// <summary> /// Returns a new x coordinate that's ensured to be outside this cuboid. Used for collision detection. /// </summary> public double pushOutX(Cuboidd from, double motx, ref EnumPushDirection direction) { direction = EnumPushDirection.None; if (from.Y2 > Y1 && from.Y1 < Y2 && from.Z2 > Z1 && from.Z1 < Z2) { if (motx > 0.0D && from.X2 <= X1 && X1 - from.X2 < motx) { direction = EnumPushDirection.Positive; motx = X1 - from.X2; } else if (motx < 0.0D && from.X1 >= X2 && X2 - from.X1 > motx) { direction = EnumPushDirection.Negative; motx = X2 - from.X1; } } return(motx); }
/// <summary> /// Updates the velocity vector according to the amount of passed time, gravity and terrain collision. /// </summary> /// <param name="pos"></param> /// <param name="motion"></param> /// <param name="size"></param> /// <returns></returns> public EnumCollideFlags UpdateMotion(Vec3d pos, Vec3f motion, float size) { particleCollBox.Set( pos.X - size / 2, pos.Y - 0 / 2, pos.Z - size / 2, pos.X + size / 2, pos.Y + size / 2, pos.Z + size / 2 ); motion.X = GameMath.Clamp(motion.X, -MotionCap, MotionCap); motion.Y = GameMath.Clamp(motion.Y, -MotionCap, MotionCap); motion.Z = GameMath.Clamp(motion.Z, -MotionCap, MotionCap); EnumCollideFlags flags = 0; minPos.Set( (int)(particleCollBox.X1 + Math.Min(0, motion.X)), (int)(particleCollBox.Y1 + Math.Min(0, motion.Y) - 1), // -1 for the extra high collision box of fences (int)(particleCollBox.Z1 + Math.Min(0, motion.Z)) ); maxPos.Set( (int)(particleCollBox.X2 + Math.Max(0, motion.X)), (int)(particleCollBox.Y2 + Math.Max(0, motion.Y)), (int)(particleCollBox.Z2 + Math.Max(0, motion.Z)) ); CollisionBoxList.Clear(); BlockAccess.WalkBlocks(minPos, maxPos, (cblock, bpos) => { Cuboidf[] collisionBoxes = cblock.GetParticleCollisionBoxes(BlockAccess, bpos); for (int i = 0; collisionBoxes != null && i < collisionBoxes.Length; i++) { CollisionBoxList.Add(collisionBoxes[i], bpos, cblock); } }, false); // Y - Collision (Vertical) EnumPushDirection pushDirection = EnumPushDirection.None; for (int i = 0; i < CollisionBoxList.Count; i++) { blockCollBox = CollisionBoxList.cuboids[i]; motion.Y = (float)blockCollBox.pushOutY(particleCollBox, motion.Y, ref pushDirection); if (pushDirection != EnumPushDirection.None) { flags |= EnumCollideFlags.CollideY; } } particleCollBox.Translate(0, motion.Y, 0); // X - Collision (Horizontal) for (int i = 0; i < CollisionBoxList.Count; i++) { blockCollBox = CollisionBoxList.cuboids[i]; motion.X = (float)blockCollBox.pushOutX(particleCollBox, motion.X, ref pushDirection); if (pushDirection != EnumPushDirection.None) { flags |= EnumCollideFlags.CollideX; } } particleCollBox.Translate(motion.X, 0, 0); // Z - Collision (Horizontal) for (int i = 0; i < CollisionBoxList.Count; i++) { blockCollBox = CollisionBoxList.cuboids[i]; motion.Z = (float)blockCollBox.pushOutZ(particleCollBox, motion.Z, ref pushDirection); if (pushDirection != EnumPushDirection.None) { flags |= EnumCollideFlags.CollideZ; } } return(flags); }