Пример #1
0
        protected override void Render(IDrawer drawer)
        {
            TopLeftRectangle cameraRectangle = drawer.DisplayedRectangle.BoundingBox;
            TopLeftRectangle drawnRectangle  = Grid.BoundingBox;

            if (!drawnRectangle.Intersects(cameraRectangle, out TopLeftRectangle visibleRectangle))
            {
                return;
            }

            IEnumerable <int[]> indexIntersection = Grid.IndexIntersection(visibleRectangle);

            foreach (int[] indexes in indexIntersection)
            {
                if (!RenderingBehaviour(Grid[indexes], this))
                {
                    continue;
                }

                Vector2 position = Grid.ToWorldPoint(indexes);

                if (SpriteTransformer != null)
                {
                    drawer.SpriteBatchStack.Current.Draw(Source.Texture, position + Transformation.Translation, Source.Rectangle, SpriteTransformer.Color,
                                                         SceneNode.Rotation + Transformation.Rotation, SpriteTransformer.Origin, SceneNode.Scale * Transformation.Scale * SpriteTransformer.Scale, SpriteTransformer.Effects, RenderDepth);
                }
                else
                {
                    drawer.SpriteBatchStack.Current.Draw(Source.Texture, position + Transformation.Translation, Source.Rectangle, Color.White,
                                                         SceneNode.Rotation + Transformation.Rotation, Source.GetDefaultOrigin(), SceneNode.Scale * Transformation.Scale, SpriteEffects.None, RenderDepth);
                }
            }
        }
Пример #2
0
        static public IEnumerable <int[]> IndexIntersection <TOther>(
            this IGrid grid, IntersectionDelegate <TopLeftRectangle, TOther> intersectionDelegate, TOther other, Func <int, int, bool> cellSelector = null)
            where TOther : IShape
        {
            // TODO: Use better grid-shape intersection algorithm
            Rectangle gridBoundingBox = MathUtils.GetBoundingBox(other.BoundingBox.Vertices.Select(grid.ToGridPoint)).ClampToRectangle(grid.IndexesBounds());

            int[] indexes = new int[2];
            for (indexes[0] = gridBoundingBox.Y; indexes[0] <= gridBoundingBox.Bottom; indexes[0]++)
            {
                for (indexes[1] = gridBoundingBox.X; indexes[1] <= gridBoundingBox.Right; indexes[1]++)
                {
                    if (!(cellSelector?.Invoke(indexes[0], indexes[1]) ?? true))
                    {
                        continue;
                    }

                    var cellRectangle = new TopLeftRectangle(grid.ToWorldPoint(indexes), grid.Delta);
                    if (intersectionDelegate(cellRectangle, other))
                    {
                        yield return(indexes);
                    }
                }
            }
        }
Пример #3
0
        static public void GetBoundingBox()
        {
            var pointA = new Vector2(-2, 1);
            var pointB = new Vector2(2, 3);
            var pointC = new Vector2(-3, -4);

            TopLeftRectangle result = MathUtils.GetBoundingBox(pointA, pointB, pointC);

            Assert.AreEqual(-3, result.Left);
            Assert.AreEqual(2, result.Right);
            Assert.AreEqual(-4, result.Top);
            Assert.AreEqual(3, result.Bottom);

            result = MathUtils.GetBoundingBox((IEnumerable <Vector2>)null);
            Assert.AreEqual(0, result.Left);
            Assert.AreEqual(0, result.Right);
            Assert.AreEqual(0, result.Top);
            Assert.AreEqual(0, result.Bottom);

            result = MathUtils.GetBoundingBox(new Vector2[0]);
            Assert.AreEqual(0, result.Left);
            Assert.AreEqual(0, result.Right);
            Assert.AreEqual(0, result.Top);
            Assert.AreEqual(0, result.Bottom);

            var rectangleA = new TopLeftRectangle(-3, -2, 1, 1);
            var rectangleB = new TopLeftRectangle(2, 1, 3, 3);
            var rectangleC = new TopLeftRectangle(-4, -5, 2, 10);

            result = MathUtils.GetBoundingBox(rectangleA, rectangleB, rectangleC);
            Assert.AreEqual(-4, result.Left);
            Assert.AreEqual(5, result.Right);
            Assert.AreEqual(-5, result.Top);
            Assert.AreEqual(5, result.Bottom);

            result = MathUtils.GetBoundingBox((IEnumerable <TopLeftRectangle>)null);
            Assert.AreEqual(0, result.Left);
            Assert.AreEqual(0, result.Right);
            Assert.AreEqual(0, result.Top);
            Assert.AreEqual(0, result.Bottom);

            result = MathUtils.GetBoundingBox(new TopLeftRectangle[0]);
            Assert.AreEqual(0, result.Left);
            Assert.AreEqual(0, result.Right);
            Assert.AreEqual(0, result.Top);
            Assert.AreEqual(0, result.Bottom);

            var circleA = new Circle(new Vector2(-2, -2), 3);
            var circleB = new Circle(new Vector2(2, 2), 5);
            var circleC = new Circle(new Vector2(5, 8), 2);

            result = MathUtils.GetBoundingBox(circleA, circleB, circleC);
            Assert.AreEqual(-5, result.Left);
            Assert.AreEqual(7, result.Right);
            Assert.AreEqual(-5, result.Top);
            Assert.AreEqual(10, result.Bottom);
        }
Пример #4
0
        protected override void Render(IDrawer drawer)
        {
            TopLeftRectangle cameraRectangle = drawer.DisplayedRectangle.BoundingBox;
            TopLeftRectangle drawnRectangle  = _fillingRectangle.Rectangle.BoundingBox;

            if (!drawnRectangle.Intersects(cameraRectangle, out TopLeftRectangle visibleRectangle))
            {
                return;
            }

            TopLeftRectangle sourceRectangle = Source.GetDrawnRectangle().ToFloats();

            Vector2 diff              = cameraRectangle.Position - drawnRectangle.Position;
            Vector2 sourcePatchInit   = new Vector2(MathHelper.Max(diff.X, 0), MathHelper.Max(diff.Y, 0));
            Vector2 sourcePatchOrigin = sourcePatchInit;

            float y = 0;

            while (y < visibleRectangle.Height)
            {
                float sourceRemainingHeight      = sourceRectangle.Height - sourcePatchOrigin.Y;
                float destinationRemainingHeight = visibleRectangle.Height - y;
                float sourcePatchHeight          = MathHelper.Min(sourceRemainingHeight, destinationRemainingHeight);

                sourcePatchOrigin.X = sourcePatchInit.X;

                float x = 0;
                while (x < visibleRectangle.Width)
                {
                    float sourceRemainingWidth      = sourceRectangle.Width - sourcePatchOrigin.X;
                    float destinationRemainingWidth = visibleRectangle.Width - x;
                    float sourcePatchWidth          = MathHelper.Min(sourceRemainingWidth, destinationRemainingWidth);

                    Vector2 position    = visibleRectangle.Position + (SceneNode.Transform(new Vector2(x, y)) - SceneNode.Position);
                    var     sourcePatch = new TopLeftRectangle(sourcePatchOrigin, new Vector2(sourcePatchWidth, sourcePatchHeight));

                    if (SpriteTransformer != null)
                    {
                        drawer.SpriteBatchStack.Current.Draw(Source.Texture, position, sourcePatch.ToIntegers(), SpriteTransformer.Color,
                                                             SceneNode.Rotation, Vector2.Zero, SceneNode.Scale * SpriteTransformer.Scale, SpriteTransformer.Effects, SceneNode.Depth);
                    }
                    else
                    {
                        drawer.SpriteBatchStack.Current.Draw(Source.Texture, position, sourcePatch.ToIntegers(), Color.White,
                                                             SceneNode.Rotation, Vector2.Zero, SceneNode.Scale, SpriteEffects.None, SceneNode.Depth);
                    }

                    x += sourcePatchWidth;
                    sourcePatchOrigin.X = sourceRectangle.Position.X;
                }

                y += sourcePatchHeight;
                sourcePatchOrigin.Y = sourceRectangle.Position.Y;
            }
        }
Пример #5
0
        public Vector2[] GetVertexTextureCoordinates(IReadOnlyList <Vector2> vertices)
        {
            var textureCoordinates = new Vector2[vertices.Count];

            TopLeftRectangle boundingBox = MathUtils.GetBoundingBox(vertices);

            for (int i = 0; i < textureCoordinates.Length; i++)
            {
                textureCoordinates[i] = vertices[i].Rescale(boundingBox, new TopLeftRectangle(0, 0, 1, 1));
            }

            return(textureCoordinates);
        }
Пример #6
0
        public IEnumerable <IPartitioner> Subdivide()
        {
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    var rectangle = new TopLeftRectangle
                    {
                        Position = BoundingBox.Position + new Vector2(j, i) * BoundingBox.Size / 2,
                        Size     = BoundingBox.Size / 2
                    };

                    yield return(new QuadtreePartitioner(rectangle, Capacity));
                }
            }
        }
Пример #7
0
        public IEnumerable <IWriteableSpace <T> > GetAllPartitionsInRange(TopLeftRectangle range)
        {
            if (_partitioner != null && !_partitioner.Intersects(range))
            {
                yield break;
            }

            if (_partitions.Count == 0)
            {
                yield return(this);

                yield break;
            }

            foreach (IWriteableSpace <T> partition in _partitions)
            {
                foreach (IWriteableSpace <T> result in partition.GetAllPartitionsInRange(range))
                {
                    yield return(result);
                }
            }
        }
Пример #8
0
 IEnumerable <ISpace> ISpace.GetAllPartitionsInRange(TopLeftRectangle range) => ((ISpace)_space).GetAllPartitionsInRange(range);
Пример #9
0
 public IEnumerable <ISpace <T> > GetAllPartitionsInRange(TopLeftRectangle range) => ((ISpace <T>)_space).GetAllPartitionsInRange(range);
Пример #10
0
 public QuadtreePartitioner(TopLeftRectangle bounds, int capacity)
 {
     BoundingBox = bounds;
     Capacity    = capacity;
 }
Пример #11
0
 static public Quad Transform(this ITransformer transformer, TopLeftRectangle topLeftRectangle)
 {
     return(new Quad(transformer.Transform(topLeftRectangle.Position), transformer.Transform(topLeftRectangle.P1), transformer.Transform(topLeftRectangle.P2)));
 }
Пример #12
0
 public IEnumerable <ISpace> GetAllPartitionsInRange(TopLeftRectangle range) => _space.GetAllPartitionsInRange(range);
Пример #13
0
 IEnumerable <ISpace> ISpace.GetAllPartitionsInRange(TopLeftRectangle range)
 {
     return(GetAllPartitionsInRange(range));
 }
Пример #14
0
        static public bool IsShapeCollidingGrid <TShape>(CollisionDelegate <TShape, TopLeftRectangle> rectangleCollisionDelegate,
                                                         ICollider <TShape> shapeCollider, IGridCollider gridCollider, out Collision collision)
            where TShape : IShape
        {
            IEnumerable <int[]> shapeGridBox = gridCollider.Grid.IndexIntersection(
                (x, y) => rectangleCollisionDelegate(y, x, out _),
                shapeCollider.Shape,
                (i, j) => gridCollider.IsCollidableCase(shapeCollider, i, j));

            foreach (int[] indexes in shapeGridBox)
            {
                int i = indexes[0];
                int j = indexes[1];

                var rectangle = new TopLeftRectangle(gridCollider.Grid.ToWorldPoint(i, j), gridCollider.Grid.Delta);

                bool colliding = false;
                for (int x = -1; x <= 1 && !colliding; x++)
                {
                    for (int y = -1; y <= 1 && !colliding; y++)
                    {
                        if ((x + y) % 2 == 0)
                        {
                            continue;
                        }

                        if (!gridCollider.Grid.ContainsPoint(i + y, j + x) || !gridCollider.IsCollidableCase(shapeCollider, i + y, j + x))
                        {
                            continue;
                        }

                        var otherCase = new TopLeftRectangle(gridCollider.Grid.ToWorldPoint(i + y, j + x), gridCollider.Grid.Delta);

                        if (!rectangleCollisionDelegate(shapeCollider.Shape, otherCase, out _))
                        {
                            continue;
                        }

                        rectangle = new TopLeftRectangle
                        {
                            Position = (gridCollider.Grid.ToWorldPoint(i, j) + gridCollider.Grid.ToWorldPoint(i + y, j + x)) * 0.5f,
                            Size     = gridCollider.Grid.Delta + gridCollider.Grid.Delta.Multiply(System.Math.Abs(x), System.Math.Abs(y))
                        };

                        colliding = true;
                    }
                }

                if (!rectangleCollisionDelegate(shapeCollider.Shape, rectangle, out Vector2 correction))
                {
                    continue;
                }

                collision = new Collision
                {
                    Sender        = shapeCollider,
                    OtherCollider = gridCollider,
                    Correction    = correction
                };

                return(true);
            }

            collision = new Collision();
            return(false);
        }
Пример #15
0
 static public Rectangle ToIntegers(this TopLeftRectangle value)
 {
     return(new Rectangle((int)value.Left, (int)value.Top, (int)value.Width, (int)value.Height));
 }