Exemple #1
0
 public IEnumerable<EntityBase> GetEntitiesWithinBoundingBoxExcludingEntity(EntityBase entity, BoundingBox boundingBox)
 {
     return (from e in Server.GetEntitiesWithinBoundingBox(boundingBox)
            where e != entity
            select e);
 }
Exemple #2
0
        /// <summary>
        /// Yields each <see cref="StructBlock"/> found within the bounds of a <see cref="BoundingBox"/>
        /// </summary>
        /// <param name="boundingBox"></param>
        /// <returns></returns>
        public IEnumerable<StructBlock> GetBlocksInBoundingBox(BoundingBox boundingBox)
        {
            UniversalCoords minimum =
                UniversalCoords.FromAbsWorld(
                    boundingBox.Minimum.X < 0.0 ? boundingBox.Minimum.X - 1.0 : boundingBox.Minimum.X,
                    boundingBox.Minimum.Y < 0.0 ? boundingBox.Minimum.Y - 1.0 : boundingBox.Minimum.Y,
                    boundingBox.Minimum.Z < 0.0 ? boundingBox.Minimum.Z - 1.0 : boundingBox.Minimum.Z);
            UniversalCoords maximum = UniversalCoords.FromAbsWorld(boundingBox.Maximum.X + 1.0,
                                                                   boundingBox.Maximum.Y + 1.0,
                                                                   boundingBox.Maximum.Z + 1.0);

            return GetBlocksBetweenCoords(minimum, maximum);
        }
Exemple #3
0
        public BoundingBox[] GetCollidingBoundingBoxes(EntityBase entity, BoundingBox boundingBox)
        {
            List<BoundingBox > collidingBoundingBoxes = new List<BoundingBox>();

            UniversalCoords minimumBlockXYZ = UniversalCoords.FromAbsWorld(boundingBox.Minimum.X, boundingBox.Minimum.Y, boundingBox.Minimum.Z);
            UniversalCoords maximumBlockXYZ = UniversalCoords.FromAbsWorld(boundingBox.Maximum.X + 1.0D, boundingBox.Maximum.Y + 1.0D, boundingBox.Maximum.Z + 1.0D);

            for (int x = minimumBlockXYZ.WorldX; x < maximumBlockXYZ.WorldX; x++)
            {
                for (int z = minimumBlockXYZ.WorldZ; z < maximumBlockXYZ.WorldZ; z++)
                {
                    Chunk chunk = GetChunkFromWorld(x, z);

                    if (chunk == null)
                        continue;

                    for (int y = minimumBlockXYZ.WorldY - 1; y < maximumBlockXYZ.WorldY; y++)
                    {
                        StructBlock block = chunk.GetBlock(UniversalCoords.FromWorld(x, y, z));

                        BlockBase blockInstance = BlockHelper.Instance(block.Type);

                        if (blockInstance != null && blockInstance.IsCollidable)
                        {
                            BoundingBox blockBox = blockInstance.GetCollisionBoundingBox(block);
                            if (blockBox.IntersectsWith(boundingBox))
                            {
                                collidingBoundingBoxes.Add(blockBox);
                            }
                        }
                    }
                }
            }

            foreach (var e in GetEntitiesWithinBoundingBoxExcludingEntity(entity, boundingBox.Expand(new Vector3(0.25, 0.25, 0.25))))
            {
                collidingBoundingBoxes.Add(e.BoundingBox);

                // TODO: determine if overridable collision boxes between two entities is necessary
                BoundingBox? collisionBox = entity.GetCollisionBox(e);
                if (collisionBox != null && collisionBox.Value != e.BoundingBox && collisionBox.Value.IntersectsWith(boundingBox))
                {
                    collidingBoundingBoxes.Add(collisionBox.Value);
                }
            }

            return collidingBoundingBoxes.ToArray();
        }
Exemple #4
0
 /// <summary>
 /// Yields an enumerable of entities where their BoundingBox intersects with <paramref name="boundingBox"/>
 /// </summary>
 /// <returns>
 /// The entities within bounding box.
 /// </returns>
 /// <param name='boundingBox'>
 /// Bounding box.
 /// </param>
 public IEnumerable<EntityBase> GetEntitiesWithinBoundingBox(BoundingBox boundingBox)
 {
     return from e in GetEntities()
            where e.BoundingBox.IntersectsWith(boundingBox)
            select e;
 }
Exemple #5
0
        public BoundingBox[] GetCollidingBoundingBoxes(EntityBase entity, BoundingBox boundingBox)
        {
            List<BoundingBox > collidingBoundingBoxes = new List<BoundingBox>();

            UniversalCoords minimumBlockXYZ = UniversalCoords.FromWorld((int)Math.Floor(boundingBox.Minimum.X), (int)Math.Floor(boundingBox.Minimum.Y), (int)Math.Floor(boundingBox.Minimum.Z));
            UniversalCoords maximumBlockXYZ = UniversalCoords.FromWorld((int)Math.Floor(boundingBox.Maximum.X + 1.0D), (int)Math.Floor(boundingBox.Maximum.Y + 1.0D), (int)Math.Floor(boundingBox.Maximum.Z + 1.0D));

            for (int x = minimumBlockXYZ.WorldX; x < maximumBlockXYZ.WorldX; x++)
            {
                for (int z = minimumBlockXYZ.WorldZ; z < maximumBlockXYZ.WorldZ; z++)
                {
                    for (int y = minimumBlockXYZ.WorldY - 1; y < maximumBlockXYZ.WorldY; y++)
                    {
                        byte block = this.GetBlockId(x, y, z);
                        // TODO: this needs to move into block logic
                        BoundingBox blockBox = new BoundingBox(
                            new Vector3(x, y, z),
                            new Vector3(x + 1, y + 1, z + 1)
                        );
                        if (blockBox.IntersectsWith(boundingBox))
                        {
                            collidingBoundingBoxes.Add(blockBox);
                        }
                    }
                }
            }

            foreach (var e in GetEntitiesWithinBoundingBoxExcludingEntity(entity, boundingBox.Expand(new Vector3(0.25, 0.25, 0.25))))
            {
                collidingBoundingBoxes.Add(e.BoundingBox);

                // TODO: determine if overridable collision boxes between two entities is necessary
                BoundingBox? collisionBox = entity.GetCollisionBox(e);
                if (collisionBox != null && collisionBox.Value != e.BoundingBox && collisionBox.Value.IntersectsWith(boundingBox))
                {
                    collidingBoundingBoxes.Add(collisionBox.Value);
                }
            }

            return collidingBoundingBoxes.ToArray();
        }
Exemple #6
0
        /// <summary>
        /// Offsets the BoundingBox with motion, with clipping based on potential collisions.
        /// </summary>
        /// <returns>
        /// The BoundingBox in the new location after clipping, and set motion to the actual offset used after clipping is applied.
        /// </returns>
        /// <param name='motion'>
        /// Motion to be applied. The value will be changed to reflect the actual offset used after clipping is applied.
        /// </param>
        /// <param name='potentialCollisions'>
        /// Potential collisions.
        /// </param>
        public BoundingBox OffsetWithClipping(ref Vector3 motion, BoundingBox[] potentialCollisions)
        {
            if (potentialCollisions == null || potentialCollisions.Length == 0)
                return this + motion;

            BoundingBox offsetBB = this;

            // If there is Y movement, calculate new Y offset for collisions
            // Y is calculated first to adjust for jumping height/falling before applying restrictions on X and Z
            if (Math.Abs(motion.Y) >= double.Epsilon)
            {
                foreach (var collision in potentialCollisions)
                {
                    // If the collision is on the same X or Z axis, then adjust the Y movement
                    if (collision.IsVectorWithinXZ(offsetBB.Minimum) || collision.IsVectorWithinXZ(offsetBB.Maximum))
                    {
                        if (motion.Y > 0.0d && offsetBB.Maximum.Y <= collision.Minimum.Y)
                        {
                            motion.Y = Math.Min(motion.Y, collision.Minimum.Y - offsetBB.Maximum.Y);
                        }
                        else if (motion.Y < 0.0d && offsetBB.Minimum.Y >= collision.Maximum.Y)
                        {
                            motion.Y = Math.Max(motion.Y, collision.Maximum.Y - offsetBB.Minimum.Y);
                        }
                    }
                }

                offsetBB = offsetBB + new Vector3(0, motion.Y, 0);
            }

            // If there is an X movement, calculate new X offset for collisions
            if (Math.Abs(motion.X) >= double.Epsilon)
            {
                foreach (var collision in potentialCollisions)
                {
                    // If the collision is on the same Y or Z axis, then adjust the X movement
                    if (collision.IsVectorWithinYZ(offsetBB.Minimum) || collision.IsVectorWithinYZ(offsetBB.Maximum))
                    {
                        if (motion.X > 0.0d && offsetBB.Maximum.X <= collision.Minimum.X)
                        {
                            motion.X = Math.Min(motion.X, collision.Minimum.X - offsetBB.Maximum.X);
                        }
                        else if (motion.X < 0.0d && offsetBB.Minimum.X >= collision.Maximum.X)
                        {
                            motion.X = Math.Max(motion.X, collision.Maximum.X - offsetBB.Minimum.X);
                        }
                    }
                }

                offsetBB = offsetBB + new Vector3(motion.X, 0, 0);
            }

            // If there is any Z movement, calculate new Z offset based on any collisions
            if (Math.Abs(motion.Z) >= double.Epsilon)
            {
                foreach (var collision in potentialCollisions)
                {
                    // If the collision is on the same Y or Z axis, then adjust the X movement
                    if (collision.IsVectorWithinXY(offsetBB.Minimum) || collision.IsVectorWithinXY(offsetBB.Maximum))
                    {
                        if (motion.Z > 0.0d && offsetBB.Maximum.Z <= collision.Minimum.Z)
                        {
                            motion.Z = Math.Min(motion.Z, collision.Minimum.Z - offsetBB.Maximum.Z);
                        }
                        else if (motion.Z < 0.0d && offsetBB.Minimum.Z >= collision.Maximum.Z)
                        {
                            motion.Z = Math.Max(motion.Z, collision.Maximum.Z - offsetBB.Minimum.Z);
                        }
                    }
                }

                offsetBB = offsetBB + new Vector3(motion.X, 0, 0);
            }

            return offsetBB;
        }
Exemple #7
0
 /// <summary>
 /// Determines if this intersects with <paramref name="boundingBox"/>.
 /// </summary>
 /// <returns>
 /// If true the bounding boxes intersect
 /// </returns>
 /// <param name='boundingBox'>
 /// The bounding box to check for an intersection with
 /// </param>
 public bool IntersectsWith(BoundingBox boundingBox)
 {
     return boundingBox.Maximum.X > Minimum.X && boundingBox.Minimum.X < Maximum.X &&
            boundingBox.Maximum.Y > Minimum.Y && boundingBox.Minimum.Y < Maximum.Y &&
            boundingBox.Maximum.Z > Minimum.Z && boundingBox.Minimum.Z < Maximum.Z;
 }
Exemple #8
0
 public bool Equals(BoundingBox other)
 {
     return other._minimum.Equals(_minimum) && other._maximum.Equals(_maximum);
 }