示例#1
0
        public static EnumIntersect AabbIntersect(Cuboidd aabb, Cuboidd aabb2, Vec3d motion)
        {
            bool beforeIntersect = aabb.Intersects(aabb2);

            if (beforeIntersect)
            {
                return(EnumIntersect.Stuck);
            }

            // X
            bool xIntersect =
                aabb.X1 <aabb2.X2 + motion.X &&
                         aabb.Y1 <aabb2.Y2 &&
                                  aabb.Z1 <aabb2.Z2 &&
                                           aabb.X2> aabb2.X1 + motion.X &&
                                  aabb.Y2> aabb2.Y1 &&
                         aabb.Z2> aabb2.Z1
            ;

            if (xIntersect)
            {
                return(EnumIntersect.IntersectX);
            }

            // Y
            bool yIntersect =
                aabb.X1 <aabb2.X2 &&
                         aabb.Y1 <aabb2.Y2 + motion.Y &&
                                  aabb.Z1 <aabb2.Z2 &&
                                           aabb.X2> aabb2.X1 &&
                                  aabb.Y2> aabb2.Y1 + motion.Y &&
                         aabb.Z2> aabb2.Z1
            ;

            if (yIntersect)
            {
                return(EnumIntersect.IntersectY);
            }

            // Z
            bool zIntersect =
                aabb.X1 <aabb2.X2 &&
                         aabb.Y1 <aabb2.Y2 &&
                                  aabb.Z1 <aabb2.Z2 + motion.Z &&
                                           aabb.X2> aabb2.X1 &&
                                  aabb.Y2> aabb2.Y1 &&
                         aabb.Z2> aabb2.Z1 + motion.Z
            ;

            if (zIntersect)
            {
                return(EnumIntersect.IntersectZ);
            }

            return(EnumIntersect.NoIntersect);
        }
示例#2
0
        public Block GetCollidingBlock(IBlockAccessor blockAccessor, Cuboidf entityBoxRel, Vec3d pos, bool alsoCheckTouch = true)
        {
            Cuboidd entityBox = tmpBox.Set(entityBoxRel).Translate(pos);

            int minX = (int)(entityBoxRel.X1 + pos.X);
            int minY = (int)(entityBoxRel.Y1 + pos.Y - 1);  // -1 for the extra high collision box of fences
            int minZ = (int)(entityBoxRel.Z1 + pos.Z);

            int maxX = (int)(entityBoxRel.X2 + pos.X);
            int maxY = (int)(entityBoxRel.Y2 + pos.Y);
            int maxZ = (int)(entityBoxRel.Z2 + pos.Z);

            for (int y = minY; y <= maxY; y++)
            {
                for (int x = minX; x <= maxX; x++)
                {
                    for (int z = minZ; z <= maxZ; z++)
                    {
                        Block block = blockAccessor.GetBlock(x, y, z);
                        blockPos.Set(x, y, z);
                        blockPosVec.Set(x, y, z);

                        Cuboidf[] collisionBoxes = block.GetCollisionBoxes(blockAccessor, blockPos);

                        for (int i = 0; collisionBoxes != null && i < collisionBoxes.Length; i++)
                        {
                            Cuboidf collBox = collisionBoxes[i];
                            if (collBox == null)
                            {
                                continue;
                            }

                            bool colliding = alsoCheckTouch ? entityBox.IntersectsOrTouches(collBox, blockPosVec) : entityBox.Intersects(collBox, blockPosVec);
                            if (colliding)
                            {
                                return(block);
                            }
                        }
                    }
                }
            }

            return(null);
        }
示例#3
0
        /// <summary>
        /// Tests given cuboidf collides with the terrain. By default also checks if the cuboid is merely touching the terrain, set alsoCheckTouch to disable that.
        /// </summary>
        /// <param name="blockAccessor"></param>
        /// <param name="entityBoxRel"></param>
        /// <param name="pos"></param>
        /// <param name="alsoCheckTouch"></param>
        /// <returns></returns>
        public bool GetCollidingCollisionBox(IBlockAccessor blockAccessor, Cuboidf entityBoxRel, Vec3d pos, ref Cuboidd intoCubuid, bool alsoCheckTouch = true)
        {
            BlockPos blockPos    = new BlockPos();
            Vec3d    blockPosVec = new Vec3d();
            Cuboidd  entityBox   = entityBoxRel.ToDouble().Translate(pos);

            int minX = (int)(entityBoxRel.X1 + pos.X);
            int minY = (int)(entityBoxRel.Y1 + pos.Y - 1);  // -1 for the extra high collision box of fences
            int minZ = (int)(entityBoxRel.Z1 + pos.Z);
            int maxX = (int)Math.Ceiling(entityBoxRel.X2 + pos.X);
            int maxY = (int)Math.Ceiling(entityBoxRel.Y2 + pos.Y);
            int maxZ = (int)Math.Ceiling(entityBoxRel.Z2 + pos.Z);

            for (int y = minY; y <= maxY; y++)
            {
                for (int x = minX; x <= maxX; x++)
                {
                    for (int z = minZ; z <= maxZ; z++)
                    {
                        Block block = blockAccessor.GetBlock(x, y, z);
                        blockPos.Set(x, y, z);
                        blockPosVec.Set(x, y, z);

                        Cuboidf[] collisionBoxes = block.GetCollisionBoxes(blockAccessor, blockPos);

                        for (int i = 0; collisionBoxes != null && i < collisionBoxes.Length; i++)
                        {
                            Cuboidf collBox = collisionBoxes[i];
                            if (collBox == null)
                            {
                                continue;
                            }

                            bool colliding = alsoCheckTouch ? entityBox.IntersectsOrTouches(collBox, blockPosVec) : entityBox.Intersects(collBox, blockPosVec);
                            if (colliding)
                            {
                                intoCubuid.Set(collBox).Translate(blockPos);
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
示例#4
0
        /// <summary>
        /// Tests given cuboidf collides with the terrain. By default also checks if the cuboid is merely touching the terrain, set alsoCheckTouch to disable that.
        /// </summary>
        /// <param name="blockAccessor"></param>
        /// <param name="entityBoxRel"></param>
        /// <param name="pos"></param>
        /// <param name="alsoCheckTouch"></param>
        /// <returns></returns>
        public Cuboidd GetCollidingCollisionBox(IBlockAccessor blockAccessor, Cuboidf entityBoxRel, Vec3d pos, bool alsoCheckTouch = true)
        {
            BlockPos blockPos    = new BlockPos();
            Vec3d    blockPosVec = new Vec3d();
            Cuboidd  entityBox   = entityBoxRel.ToDouble().Translate(pos);

            entityBox.Y1 = Math.Round(entityBox.Y1, 5); // Fix float/double rounding errors. Only need to fix the vertical because gravity.

            int minX = (int)(entityBoxRel.X1 + pos.X);
            int minY = (int)(entityBoxRel.Y1 + pos.Y - 1);  // -1 for the extra high collision box of fences
            int minZ = (int)(entityBoxRel.Z1 + pos.Z);
            int maxX = (int)Math.Ceiling(entityBoxRel.X2 + pos.X);
            int maxY = (int)Math.Ceiling(entityBoxRel.Y2 + pos.Y);
            int maxZ = (int)Math.Ceiling(entityBoxRel.Z2 + pos.Z);

            for (int y = minY; y <= maxY; y++)
            {
                for (int x = minX; x <= maxX; x++)
                {
                    for (int z = minZ; z <= maxZ; z++)
                    {
                        Block block = blockAccessor.GetBlock(x, y, z);
                        blockPos.Set(x, y, z);
                        blockPosVec.Set(x, y, z);

                        Cuboidf[] collisionBoxes = block.GetCollisionBoxes(blockAccessor, blockPos);

                        for (int i = 0; collisionBoxes != null && i < collisionBoxes.Length; i++)
                        {
                            Cuboidf collBox = collisionBoxes[i];
                            if (collBox == null)
                            {
                                continue;
                            }

                            bool colliding = alsoCheckTouch ? entityBox.IntersectsOrTouches(collBox, blockPosVec) : entityBox.Intersects(collBox, blockPosVec);
                            if (colliding)
                            {
                                return(collBox.ToDouble().Translate(blockPos));
                            }
                        }
                    }
                }
            }

            return(null);
        }