diff --git a/src/MineCase.Algorithm/Collision.cs b/src/MineCase.Algorithm/Collision.cs new file mode 100644 index 00000000..a0ae7849 --- /dev/null +++ b/src/MineCase.Algorithm/Collision.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using MineCase.Graphics; +using MineCase.Server.Game; +using MineCase.World; + +namespace MineCase.Algorithm +{ + public static class Collision + { + public static bool IsCollided(Shape shape1, Shape shape2) + { + return shape1.CollideWith(shape2); + } + } +} diff --git a/src/MineCase.Core/BoundingBox.cs b/src/MineCase.Core/BoundingBox.cs new file mode 100644 index 00000000..713f7f3c --- /dev/null +++ b/src/MineCase.Core/BoundingBox.cs @@ -0,0 +1,840 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Text; + +namespace MineCase +{ + public static class BoundingBox + { + public static Vector3 Item() + { + return new Vector3 + { + X = 0.25f, + Z = 0.25f, + Y = 0.25f + }; + } + + public static Vector3 XPOrb() + { + return new Vector3 + { + X = 0.5f, + Z = 0.5f, + Y = 0.5f + }; + } + + public static Vector3 AreaEffectCloud(float radius) + { + return new Vector3 + { + X = 2.0f * radius, + Z = 2.0f * radius, + Y = 0.5f + }; + } + + public static Vector3 ElderGuardian() + { + return new Vector3 + { + X = 1.9975f, + Z = 1.9975f, + Y = 1.9975f + }; + } + + public static Vector3 WitherSkeleton() + { + return new Vector3 + { + X = 0.7f, + Z = 0.7f, + Y = 2.4f + }; + } + + public static Vector3 Stray() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.99f + }; + } + + public static Vector3 ThrownEgg() + { + return new Vector3 + { + X = 0.25f, + Z = 0.25f, + Y = 0.25f + }; + } + + public static Vector3 LeashKnot() + { + return new Vector3 + { + X = 0.375f, + Z = 0.375f, + Y = 0.5f + }; + } + + public static Vector3 Painting() + { + return new Vector3 + { + X = 0f, // TODO: type width or 0.0625 (depth), + Z = 0f, // TODO: type width or 0.0625 (depth), + Y = 0f, // TODO: type height + }; + } + + public static Vector3 Arrow() + { + return new Vector3 + { + X = 0.5f, + Z = 0.5f, + Y = 0.5f + }; + } + + public static Vector3 Snowball() + { + return new Vector3 + { + X = 0.25f, + Z = 0.25f, + Y = 0.25f + }; + } + + public static Vector3 Fireball() + { + return new Vector3 + { + X = 1.0f, + Z = 1.0f, + Y = 1.0f + }; + } + + public static Vector3 SmallFireball() + { + return new Vector3 + { + X = 0.3125f, + Z = 0.3125f, + Y = 0.3125f + }; + } + + public static Vector3 ThrownEnderpearl() + { + return new Vector3 + { + X = 0.25f, + Z = 0.25f, + Y = 0.25f + }; + } + + public static Vector3 EyeOfEnderSignal() + { + return new Vector3 + { + X = 0.25f, + Z = 0.25f, + Y = 0.25f + }; + } + + public static Vector3 ThrownPotion() + { + return new Vector3 + { + X = 0.25f, + Z = 0.25f, + Y = 0.25f + }; + } + + public static Vector3 ThrownExpBottle() + { + return new Vector3 + { + X = 0.25f, + Z = 0.25f, + Y = 0.25f + }; + } + + public static Vector3 ItemFrame() + { + return new Vector3 + { + X = 0f, // TODO: 0.75 or 0.0625 (depth), + Z = 0f, // TODO: 0.75 or 0.0625 (depth), + Y = 0.75f + }; + } + + public static Vector3 WitherSkull() + { + return new Vector3 + { + X = 0.3125f, + Z = 0.3125f, + Y = 0.3125f + }; + } + + public static Vector3 PrimedTnt() + { + return new Vector3 + { + X = 0.98f, + Z = 0.98f, + Y = 0.98f + }; + } + + public static Vector3 FallingSand() + { + return new Vector3 + { + X = 0.98f, + Z = 0.98f, + Y = 0.98f + }; + } + + public static Vector3 FireworksRocketEntity() + { + return new Vector3 + { + X = 0.25f, + Z = 0.25f, + Y = 0.25f + }; + } + + public static Vector3 Husk() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.95f + }; + } + + public static Vector3 SpectralArrow() + { + return new Vector3 + { + X = 0.5f, + Z = 0.5f, + Y = 0.5f + }; + } + + public static Vector3 ShulkerBullet() + { + return new Vector3 + { + X = 0.3125f, + Z = 0.3125f, + Y = 0.3125f + }; + } + + public static Vector3 DragonFireball() + { + return new Vector3 + { + X = 1.0f, + Z = 1.0f, + Y = 1.0f + }; + } + + public static Vector3 ZombieVillager() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.95f + }; + } + + public static Vector3 SkeletonHorse() + { + return new Vector3 + { + X = 1.3964844f, + Z = 1.3964844f, + Y = 1.6f + }; + } + + public static Vector3 ZombieHorse() + { + return new Vector3 + { + X = 1.3964844f, + Z = 1.3964844f, + Y = 1.6f + }; + } + + public static Vector3 ArmorStand() + { + return new Vector3 + { + X = 0f, // TODO: normal: 0.5 marker: 0.0 small: 0.25, + Z = 0f, // TODO: normal: 0.5 marker: 0.0 small: 0.25, + Y = 0f, // TODO: normal: 1.975 marker: 0.0 small: 0.9875 + }; + } + + public static Vector3 Donkey() + { + return new Vector3 + { + X = 1.3964844f, + Z = 1.3964844f, + Y = 1.6f + }; + } + + public static Vector3 Mule() + { + return new Vector3 + { + X = 1.3964844f, + Z = 1.3964844f, + Y = 1.6f + }; + } + + public static Vector3 EvocationFangs() + { + return new Vector3 + { + X = 0.5f, + Z = 0.5f, + Y = 0.8f + }; + } + + public static Vector3 EvocationIllager() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.95f + }; + } + + public static Vector3 Vex() + { + return new Vector3 + { + X = 0.4f, + Z = 0.4f, + Y = 0.8f + }; + } + + public static Vector3 VindicationIllager() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.95f + }; + } + + public static Vector3 IllusionIllager() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.95f + }; + } + + public static Vector3 MinecartCommandBlock() + { + return new Vector3 + { + X = 0.98f, + Z = 0.98f, + Y = 0.7f + }; + } + + public static Vector3 Boat() + { + return new Vector3 + { + X = 1.375f, + Z = 1.375f, + Y = 0.5625f + }; + } + + public static Vector3 MinecartRideable() + { + return new Vector3 + { + X = 0.98f, + Z = 0.98f, + Y = 0.7f + }; + } + + public static Vector3 MinecartChest() + { + return new Vector3 + { + X = 0.98f, + Z = 0.98f, + Y = 0.7f + }; + } + + public static Vector3 MinecartFurnace() + { + return new Vector3 + { + X = 0.98f, + Z = 0.98f, + Y = 0.7f + }; + } + + public static Vector3 MinecartTNT() + { + return new Vector3 + { + X = 0.98f, + Z = 0.98f, + Y = 0.7f + }; + } + + public static Vector3 MinecartHopper() + { + return new Vector3 + { + X = 0.98f, + Z = 0.98f, + Y = 0.7f + }; + } + + public static Vector3 MinecartSpawner() + { + return new Vector3 + { + X = 0.98f, + Z = 0.98f, + Y = 0.7f + }; + } + + public static Vector3 Creeper() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.7f + }; + } + + public static Vector3 Skeleton() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.99f + }; + } + + public static Vector3 Spider() + { + return new Vector3 + { + X = 1.4f, + Z = 1.4f, + Y = 0.9f + }; + } + + public static Vector3 Giant() + { + return new Vector3 + { + X = 3.6f, + Z = 3.6f, + Y = 10.8f + }; + } + + public static Vector3 Zombie() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.95f + }; + } + + public static Vector3 Slime(float size) + { + return new Vector3 + { + X = 0.51000005f * size, + Z = 0.51000005f * size, + Y = 0.51000005f * size + }; + } + + public static Vector3 Ghast() + { + return new Vector3 + { + X = 4f, + Z = 4f, + Y = 4f + }; + } + + public static Vector3 PigZombie() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.95f + }; + } + + public static Vector3 Enderman() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 2.9f + }; + } + + public static Vector3 CaveSpider() + { + return new Vector3 + { + X = 0.7f, + Z = 0.7f, + Y = 0.5f + }; + } + + public static Vector3 Silverfish() + { + return new Vector3 + { + X = 0.4f, + Z = 0.4f, + Y = 0.3f + }; + } + + public static Vector3 Blaze() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.8f + }; + } + + public static Vector3 LavaSlime(float size) + { + return new Vector3 + { + X = 0.51000005f * size, + Z = 0.51000005f * size, + Y = 0.51000005f * size + }; + } + + public static Vector3 EnderDragon() + { + return new Vector3 + { + X = 16.0f, + Z = 16.0f, + Y = 8.0f + }; + } + + public static Vector3 WitherBoss() + { + return new Vector3 + { + X = 0.9f, + Z = 0.9f, + Y = 3.5f + }; + } + + public static Vector3 Bat() + { + return new Vector3 + { + X = 0.5f, + Z = 0.5f, + Y = 0.9f + }; + } + + public static Vector3 Witch() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.95f + }; + } + + public static Vector3 Endermite() + { + return new Vector3 + { + X = 0.4f, + Z = 0.4f, + Y = 0.3f + }; + } + + public static Vector3 Guardian() + { + return new Vector3 + { + X = 0.85f, + Z = 0.85f, + Y = 0.85f + }; + } + + public static Vector3 Shulker() + { + return new Vector3 + { + X = 1.0f, + Z = 1.0f, + Y = 0f // TODO: 1.0-2.0 (depending on peek) + }; + } + + public static Vector3 Pig() + { + return new Vector3 + { + X = 0.9f, + Z = 0.9f, + Y = 0.9f + }; + } + + public static Vector3 Sheep() + { + return new Vector3 + { + X = 0.9f, + Z = 0.9f, + Y = 1.3f + }; + } + + public static Vector3 Cow() + { + return new Vector3 + { + X = 0.9f, + Z = 0.9f, + Y = 1.4f + }; + } + + public static Vector3 Chicken() + { + return new Vector3 + { + X = 0.4f, + Z = 0.4f, + Y = 0.7f + }; + } + + public static Vector3 Squid() + { + return new Vector3 + { + X = 0.8f, + Z = 0.8f, + Y = 0.8f + }; + } + + public static Vector3 Wolf() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 0.85f + }; + } + + public static Vector3 MushroomCow() + { + return new Vector3 + { + X = 0.9f, + Z = 0.9f, + Y = 1.4f + }; + } + + public static Vector3 SnowMan() + { + return new Vector3 + { + X = 0.7f, + Z = 0.7f, + Y = 1.9f + }; + } + + public static Vector3 Ozelot() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 0.7f + }; + } + + public static Vector3 VillagerGolem() + { + return new Vector3 + { + X = 1.4f, + Z = 1.4f, + Y = 2.7f + }; + } + + public static Vector3 Horse() + { + return new Vector3 + { + X = 1.3964844f, + Z = 1.3964844f, + Y = 1.6f + }; + } + + public static Vector3 Rabbit() + { + return new Vector3 + { + X = 0.4f, + Z = 0.4f, + Y = 0.5f + }; + } + + public static Vector3 PolarBear() + { + return new Vector3 + { + X = 1.3f, + Z = 1.3f, + Y = 1.4f + }; + } + + public static Vector3 Llama() + { + return new Vector3 + { + X = 0.9f, + Z = 0.9f, + Y = 1.87f + }; + } + + public static Vector3 LlamaSpit() + { + return new Vector3 + { + X = 0.25f, + Z = 0.25f, + Y = 0.25f + }; + } + + public static Vector3 Parrot() + { + return new Vector3 + { + X = 0.5f, + Z = 0.5f, + Y = 0.9f + }; + } + + public static Vector3 Villager() + { + return new Vector3 + { + X = 0.6f, + Z = 0.6f, + Y = 1.95f + }; + } + + public static Vector3 EnderCrystal() + { + return new Vector3 + { + X = 2.0f, + Z = 2.0f, + Y = 2.0f + }; + } + } +} diff --git a/src/MineCase.Core/Entity.cs b/src/MineCase.Core/Entity.cs new file mode 100644 index 00000000..c000997a --- /dev/null +++ b/src/MineCase.Core/Entity.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MineCase +{ + public enum EntityId : uint + { + DroppedItem = 1, + ExperienceOrb = 2, + AreaEffectCloud = 3, + LeadKnot = 8, + Painting = 9, + ItemFrame = 18, + ArmorStand = 30, + EvocationFangs = 33, + EnderCrystal = 200, + ThrownEgg = 7, + ShotArrow = 10, + ThrownSnowball = 11, + GhastFireball = 12, + BlazeFireball = 13, + ThrownEnderPearl = 14, + ThrownEyeOfEnder = 15, + ThrownSplashPotion = 16, + ThrownBottleEnchanting = 17, + WitherSkull = 19, + FireworkRocket = 22, + ShotSpectralArrow = 24, + ShulkerBullet = 25, + DragonFireball = 26, + LlamaSpit = 104, + PrimedTnt = 20, + FallingBlock = 21, + MinecartWithCommandBlock = 40, + Boat = 41, + Minecart = 42, + MinecartWithChest = 43, + MinecartWithFurnace = 44, + MinecartWithTnt = 45, + MinecartWithHopper = 46, + MinecartWithSpawner = 47, + ElderGuardian = 4, + WitherSkeleton = 5, + Stray = 6, + Husk = 23, + ZombieVillager = 27, + Evoker = 34, + Vex = 35, + Vindicator = 36, + Illusioner = 37, + Creeper = 50, + Skeleton = 51, + Spider = 52, + Giant = 53, + Zombie = 54, + Slime = 55, + Ghast = 56, + ZombiePigman = 57, + Enderman = 58, + CaveSpider = 59, + Silverfish = 60, + Blaze = 61, + MagmaCube = 66, + EnderDragon = 63, + Wither = 64, + Witch = 66, + Endermite = 67, + Guardian = 68, + Shulker = 69, + SkeletonHorse = 28, + ZombieHorse = 29, + Donkey = 31, + Mule = 32, + Bat = 65, + Pig = 90, + Sheep = 91, + Cow = 92, + Chicken = 93, + Squid = 94, + Wolf = 95, + Mooshroom = 96, + SnowGolem = 97, + Ocelot = 98, + IronGolem = 99, + Horse = 100, + Rabbit = 101, + PolarBear = 102, + Llama = 103, + Parrot = 105, + Villager = 120 + } +} diff --git a/src/MineCase.Core/Graphics/Circle.cs b/src/MineCase.Core/Graphics/Circle.cs new file mode 100644 index 00000000..f6114cb1 --- /dev/null +++ b/src/MineCase.Core/Graphics/Circle.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Text; + +namespace MineCase.Graphics +{ + public struct Circle + { + public Point2d Center { get; set; } + + public float Radius { get; set; } + + public Circle(float x, float y, float radius) + { + Center = new Point2d(x, y); + Radius = radius; + } + + public Circle(Point2d center, float radius) + { + Center = center; + Radius = radius; + } + + public bool OverlapWith(Circle circle) + { + return Radius + circle.Radius < Point2d.Distance(Center, circle.Center); + } + + public bool OverlapWith(Rect rect) + { + return rect.OverlapWith(this); + } + } +} diff --git a/src/MineCase.Core/Graphics/Cuboid.cs b/src/MineCase.Core/Graphics/Cuboid.cs new file mode 100644 index 00000000..00f1569e --- /dev/null +++ b/src/MineCase.Core/Graphics/Cuboid.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MineCase.Graphics +{ + public class Cuboid : Shape + { + public override ShapeType Type => ShapeType.Cuboid; + + public Point3d Point { get; set; } + + public Size Size { get; set; } + + public Cuboid(Point3d point, Size size) + { + Point = point; + Size = size; + } + + public bool CollideWithCuboid(Cuboid cuboid) + { + if (Point.Z + Size.Height < cuboid.Point.Z || + Point.Z > cuboid.Point.Z + cuboid.Size.Height) + return false; + Rect rect1 = new Rect + { + X = Point.X, + Y = Point.Y, + Length = Size.Length, + Width = Size.Width + }; + Rect rect2 = new Rect + { + X = cuboid.Point.X, + Y = cuboid.Point.Y, + Length = cuboid.Size.Length, + Width = cuboid.Size.Width + }; + return rect1.OverlapWith(rect2); + } + + public override bool CollideWith(Shape other) + { + switch (other.Type) + { + case ShapeType.Cuboid: + return CollideWithCuboid((Cuboid)other); + default: + break; + } + + return false; + } + } +} diff --git a/src/MineCase.Core/Graphics/Point.cs b/src/MineCase.Core/Graphics/Point.cs new file mode 100644 index 00000000..d30abfe8 --- /dev/null +++ b/src/MineCase.Core/Graphics/Point.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Text; + +namespace MineCase.Graphics +{ + public struct Point2d + { + public float X { get; set; } + + public float Y { get; set; } + + public Point2d(float x, float y) + { + X = x; + Y = y; + } + + public Point2d(Point2d point) + { + X = point.X; + Y = point.Y; + } + + public Point2d(Vector2 vector) + { + X = vector.X; + Y = vector.Y; + } + + public static float Distance(Point2d p1, Point2d p2) + { + return (float)Math.Sqrt(((p1.X - p2.X) * (p1.X - p2.X)) + (p1.Y - p2.Y) * (p1.Y - p2.Y)); + } + + public float Length() + { + return (float)Math.Sqrt(X * X + Y * Y); + } + + public float LengthSquared() + { + return Length() * Length(); + } + + public static Point2d operator + (Point2d p1, Point2d p2) + { + return new Point2d(p1.X + p2.X, p1.Y + p2.Y); + } + + public static Point2d operator - (Point2d value) + { + return new Point2d(-value.X, -value.Y); + } + + public static Point2d operator - (Point2d p1, Point2d p2) + { + return new Point2d(p1.X - p2.X, p1.Y - p2.Y); + } + } + + public struct Point3d + { + public float X { get; set; } + + public float Y { get; set; } + + public float Z { get; set; } + + public Point3d(float x, float y, float z) + { + X = x; + Y = y; + Z = z; + } + + public Point3d(Point3d point) + { + X = point.X; + Y = point.Y; + Z = point.Z; + } + + public Point3d(Vector3 vector) + { + X = vector.X; + Y = vector.Y; + Z = vector.Z; + } + } +} diff --git a/src/MineCase.Core/Graphics/Rect.cs b/src/MineCase.Core/Graphics/Rect.cs new file mode 100644 index 00000000..a8a54149 --- /dev/null +++ b/src/MineCase.Core/Graphics/Rect.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Text; + +namespace MineCase.Graphics +{ + public struct Rect + { + public float X { get; set; } + + public float Y { get; set; } + + public float Length { get; set; } + + public float Width { get; set; } + + public Rect(float x, float y, float length, float width) + { + X = x; + Y = y; + Length = length; + Width = width; + } + + public Rect(Point2d point, Size size) + { + X = point.X; + Y = point.Y; + Length = size.Length; + Width = size.Width; + } + + public Point2d BottomLeft() + { + return new Point2d(X, Y); + } + + public Point2d TopRight() + { + return new Point2d(X + Length, Y + Width); + } + + public Point2d Center() + { + return new Point2d(X + Length * 0.5f, Y + Width * 0.5f); + } + + public bool OverlapWith(Rect rect) + { + var minx = Math.Max(X, rect.X); + var miny = Math.Max(Y, rect.Y); + var maxx = Math.Min(X + Length, rect.X + rect.Length); + var maxy = Math.Min(Y + Width, rect.Y + rect.Width); + + // 边重叠也算重叠 + if (minx > maxx || miny > maxy) + return false; + return true; + } + + public bool OverlapWith(Circle circle) + { + var c = Center(); + var h = TopRight() - c; + var v = new Point2d(Math.Abs(circle.Center.X - c.X), Math.Abs(circle.Center.Y - c.Y)); + var u = v - h; + if (u.X < 0f && u.Y < 0f) + { + u.X = u.Y = 0f; + } + + return u.LengthSquared() <= circle.Radius * circle.Radius; + } + } +} diff --git a/src/MineCase.Core/Graphics/Shape.cs b/src/MineCase.Core/Graphics/Shape.cs new file mode 100644 index 00000000..593821d4 --- /dev/null +++ b/src/MineCase.Core/Graphics/Shape.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MineCase.Graphics +{ + public enum ShapeType : uint + { + Cuboid = 0 + } + + public abstract class Shape + { + public abstract ShapeType Type { get; } + + public abstract bool CollideWith(Shape other); + } +} diff --git a/src/MineCase.Core/Graphics/Size.cs b/src/MineCase.Core/Graphics/Size.cs new file mode 100644 index 00000000..ea39d970 --- /dev/null +++ b/src/MineCase.Core/Graphics/Size.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +using System.Numerics; +using System.Text; + +namespace MineCase.Graphics +{ + public struct Size + { + public float Length { get; set; } + + public float Width { get; set; } + + public float Height { get; set; } + + public Size(float length, float width, float height = 0f) + { + Contract.Assert(length >= 0f, "The parameter must be greater than or equal to zero."); + Contract.Assert(width >= 0f, "The parameter must be greater than or equal to zero."); + Contract.Assert(height >= 0f, "The parameter must be greater than or equal to zero."); + Length = length; + Width = width; + Height = height; + } + + public Size(Size size) + { + Length = size.Length; + Width = size.Width; + Height = size.Height; + } + + public float Area() + { + return Length * Width; + } + + public float Volume() + { + return Length * Width * Height; + } + } +} diff --git a/tests/UnitTest/CollisionTest.cs b/tests/UnitTest/CollisionTest.cs new file mode 100644 index 00000000..ed24d637 --- /dev/null +++ b/tests/UnitTest/CollisionTest.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MineCase.Algorithm; +using MineCase.Graphics; +using Xunit; + +namespace MineCase.UnitTest +{ + public class CollisionTest + { + [Fact] + public void TestCollsion() + { + var shape1 = new Cuboid(new Point3d(0f, 0f, 0f), new Size(1f, 1f, 2f)); + var shape2 = new Cuboid(new Point3d(0.9f, 0.9f, 1f), new Size(1f, 1f, 1f)); + var result = Collision.IsCollided(shape1, shape2); + Assert.True(result); + + shape1 = new Cuboid(new Point3d(0f, 0f, 0f), new Size(1f, 1f, 1f)); + shape2 = new Cuboid(new Point3d(-0.5f, 0.3f, 0.5f), new Size(3f, 0.1f, 0.1f)); + result = Collision.IsCollided(shape1, shape2); + Assert.True(result); + } + + [Fact] + public void TestNotCollsion() + { + var shape1 = new Cuboid(new Point3d(0f, 0f, 0f), new Size(1f, 1f, 2f)); + var shape2 = new Cuboid(new Point3d(2f, 2f, 1f), new Size(1f, 1f, 1f)); + var result = Collision.IsCollided(shape1, shape2); + Assert.False(result); + + shape1 = new Cuboid(new Point3d(0f, 0f, 0f), new Size(1f, 1f, 1f)); + shape2 = new Cuboid(new Point3d(0f, 0f, 2f), new Size(1f, 1f, 1f)); + result = Collision.IsCollided(shape1, shape2); + Assert.False(result); + } + + [Fact] + public void TestBoundaryCollsion() + { + var shape1 = new Cuboid(new Point3d(0f, 0f, 0f), new Size(1f, 1f, 2f)); + var shape2 = new Cuboid(new Point3d(1f, 0f, 0f), new Size(1f, 1f, 1f)); + var result = Collision.IsCollided(shape1, shape2); + Assert.True(result); + + shape1 = new Cuboid(new Point3d(0f, 0f, 0f), new Size(1f, 1f, 1f)); + shape2 = new Cuboid(new Point3d(0f, 0f, 1f), new Size(1f, 1f, 1f)); + result = Collision.IsCollided(shape1, shape2); + Assert.True(result); + + shape1 = new Cuboid(new Point3d(0f, 0f, 0f), new Size(1f, 1f, 1f)); + shape2 = new Cuboid(new Point3d(1f, 1f, 1f), new Size(1f, 1f, 1f)); + result = Collision.IsCollided(shape1, shape2); + Assert.True(result); + } + } +}