diff --git a/Source/Demos/Demo.BitmapFonts/Game2.cs b/Source/Demos/Demo.BitmapFonts/Game2.cs index 18c00552..a5a8fd71 100644 --- a/Source/Demos/Demo.BitmapFonts/Game2.cs +++ b/Source/Demos/Demo.BitmapFonts/Game2.cs @@ -3,8 +3,6 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using MonoGame.Extended; using MonoGame.Extended.BitmapFonts; -using MonoGame.Extended.Graphics.Effects; -using MonoGame.Extended.Shapes; using MonoGame.Extended.ViewportAdapters; namespace Demo.BitmapFonts diff --git a/Source/Demos/Demo.Platformer/Entities/Components/BasicCollisionBody.cs b/Source/Demos/Demo.Platformer/Entities/Components/BasicCollisionBody.cs index 4bdcd351..a68c5d64 100644 --- a/Source/Demos/Demo.Platformer/Entities/Components/BasicCollisionBody.cs +++ b/Source/Demos/Demo.Platformer/Entities/Components/BasicCollisionBody.cs @@ -1,7 +1,6 @@ using Microsoft.Xna.Framework; using MonoGame.Extended; using MonoGame.Extended.Entities.Components; -using MonoGame.Extended.Shapes; namespace Demo.Platformer.Entities.Components { diff --git a/Source/Demos/Demo.Platformer/Entities/Systems/BasicCollisionSystem.cs b/Source/Demos/Demo.Platformer/Entities/Systems/BasicCollisionSystem.cs index c3ad26d4..99921edf 100644 --- a/Source/Demos/Demo.Platformer/Entities/Systems/BasicCollisionSystem.cs +++ b/Source/Demos/Demo.Platformer/Entities/Systems/BasicCollisionSystem.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using Demo.Platformer.Entities.Components; @@ -60,22 +61,50 @@ namespace Demo.Platformer.Entities.Systems foreach (var bodyB in _staticBodies.Concat(_movingBodies)) { - if (bodyA != bodyB) + if (bodyA == bodyB) + continue; + + var depth = IntersectionDepth(bodyA.BoundingRectangle, bodyB.BoundingRectangle); + + if (depth != Vector2.Zero) { - var depth = bodyA.BoundingRectangle.IntersectionDepth(bodyB.BoundingRectangle); + var collisionHandlers = bodyA.Entity.GetComponents(); - if (depth != Vector2.Zero) - { - var collisionHandlers = bodyA.Entity.GetComponents(); - - foreach (var collisionHandler in collisionHandlers) - collisionHandler.OnCollision(bodyA, bodyB, depth); - } + foreach (var collisionHandler in collisionHandlers) + collisionHandler.OnCollision(bodyA, bodyB, depth); } } } } + + public Vector2 IntersectionDepth(RectangleF first, RectangleF second) + { + // Calculate half sizes. + var thisHalfWidth = first.Width / 2.0f; + var thisHalfHeight = first.Height / 2.0f; + var otherHalfWidth = second.Width / 2.0f; + var otherHalfHeight = second.Height / 2.0f; + + // Calculate centers. + var centerA = new Vector2(first.Left + thisHalfWidth, first.Top + thisHalfHeight); + var centerB = new Vector2(second.Left + otherHalfWidth, second.Top + otherHalfHeight); + + // Calculate current and minimum-non-intersecting distances between centers. + var distanceX = centerA.X - centerB.X; + var distanceY = centerA.Y - centerB.Y; + var minDistanceX = thisHalfWidth + otherHalfWidth; + var minDistanceY = thisHalfHeight + otherHalfHeight; + + // If we are not intersecting at all, return (0, 0). + if ((Math.Abs(distanceX) >= minDistanceX) || (Math.Abs(distanceY) >= minDistanceY)) + return Vector2.Zero; + + // Calculate and return intersection depths. + var depthX = distanceX > 0 ? minDistanceX - distanceX : -minDistanceX - distanceX; + var depthY = distanceY > 0 ? minDistanceY - distanceY : -minDistanceY - distanceY; + return new Vector2(depthX, depthY); + } } } \ No newline at end of file diff --git a/Source/Demos/Demo.Screens/Screens/MenuItem.cs b/Source/Demos/Demo.Screens/Screens/MenuItem.cs index f26ed73c..c28a78bb 100644 --- a/Source/Demos/Demo.Screens/Screens/MenuItem.cs +++ b/Source/Demos/Demo.Screens/Screens/MenuItem.cs @@ -1,8 +1,8 @@ using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using MonoGame.Extended; using MonoGame.Extended.BitmapFonts; -using MonoGame.Extended.Shapes; namespace Demo.Screens.Screens { diff --git a/Source/Demos/Demo.Screens/Screens/MenuScreen.cs b/Source/Demos/Demo.Screens/Screens/MenuScreen.cs index 8ff97fab..2ca8fd62 100644 --- a/Source/Demos/Demo.Screens/Screens/MenuScreen.cs +++ b/Source/Demos/Demo.Screens/Screens/MenuScreen.cs @@ -4,6 +4,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; +using MonoGame.Extended; using MonoGame.Extended.BitmapFonts; using MonoGame.Extended.Screens; @@ -78,7 +79,7 @@ namespace Demo.Screens.Screens foreach (var menuItem in MenuItems) { - var isHovered = menuItem.BoundingRectangle.Contains(mouseState.X, mouseState.Y); + var isHovered = menuItem.BoundingRectangle.Contains(new Point2(mouseState.X, mouseState.Y)); menuItem.Color = isHovered ? Color.Yellow : Color.White; diff --git a/Source/Demos/Demo.SpaceGame/Entities/Meteor.cs b/Source/Demos/Demo.SpaceGame/Entities/Meteor.cs index d9bc1f37..05b85096 100644 --- a/Source/Demos/Demo.SpaceGame/Entities/Meteor.cs +++ b/Source/Demos/Demo.SpaceGame/Entities/Meteor.cs @@ -1,6 +1,6 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using MonoGame.Extended.Shapes; +using MonoGame.Extended; using MonoGame.Extended.Sprites; using MonoGame.Extended.TextureAtlases; diff --git a/Source/Demos/Demo.SpaceGame/Entities/MeteorFactory.cs b/Source/Demos/Demo.SpaceGame/Entities/MeteorFactory.cs index 878df780..4f43cb23 100644 --- a/Source/Demos/Demo.SpaceGame/Entities/MeteorFactory.cs +++ b/Source/Demos/Demo.SpaceGame/Entities/MeteorFactory.cs @@ -4,7 +4,6 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using MonoGame.Extended; -using MonoGame.Extended.Shapes; using MonoGame.Extended.TextureAtlases; namespace Demo.SpaceGame.Entities @@ -73,7 +72,7 @@ namespace Demo.SpaceGame.Entities } } - public void SpawnNewMeteor(Vector2 playerPosition) + public void SpawnNewMeteor(Point2 playerPosition) { var rotationSpeed = _random.Next(-10, 10) * 0.1f; var spawnCircle = new CircleF(playerPosition, 630); diff --git a/Source/Demos/Demo.SpaceGame/Entities/Spaceship.cs b/Source/Demos/Demo.SpaceGame/Entities/Spaceship.cs index 7d1b8b38..2b30fcf0 100644 --- a/Source/Demos/Demo.SpaceGame/Entities/Spaceship.cs +++ b/Source/Demos/Demo.SpaceGame/Entities/Spaceship.cs @@ -2,7 +2,6 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MonoGame.Extended; -using MonoGame.Extended.Shapes; using MonoGame.Extended.Sprites; using MonoGame.Extended.TextureAtlases; diff --git a/Source/Demos/Demo.SpaceGame/Game1.cs b/Source/Demos/Demo.SpaceGame/Game1.cs index e2f6e28a..afbe3acd 100644 --- a/Source/Demos/Demo.SpaceGame/Game1.cs +++ b/Source/Demos/Demo.SpaceGame/Game1.cs @@ -6,7 +6,6 @@ using Microsoft.Xna.Framework.Input; using MonoGame.Extended; using MonoGame.Extended.Animations.SpriteSheets; using MonoGame.Extended.BitmapFonts; -using MonoGame.Extended.Shapes; using MonoGame.Extended.TextureAtlases; using MonoGame.Extended.ViewportAdapters; diff --git a/Source/Demos/Demo.SpriteSheetAnimations/Zombie.cs b/Source/Demos/Demo.SpriteSheetAnimations/Zombie.cs index b2803677..5db5cd1a 100644 --- a/Source/Demos/Demo.SpriteSheetAnimations/Zombie.cs +++ b/Source/Demos/Demo.SpriteSheetAnimations/Zombie.cs @@ -5,7 +5,6 @@ using MonoGame.Extended; using MonoGame.Extended.Animations; using MonoGame.Extended.Animations.SpriteSheets; using MonoGame.Extended.Collisions; -using MonoGame.Extended.Shapes; using MonoGame.Extended.Sprites; namespace Demo.SpriteSheetAnimations diff --git a/Source/Demos/Demo.Sprites/Game1.cs b/Source/Demos/Demo.Sprites/Game1.cs index 9d38e755..d50767e5 100644 --- a/Source/Demos/Demo.Sprites/Game1.cs +++ b/Source/Demos/Demo.Sprites/Game1.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; +using MonoGame.Extended; using MonoGame.Extended.Shapes; using MonoGame.Extended.Sprites; using MonoGame.Extended.TextureAtlases; diff --git a/Source/Demos/Demo.TiledMaps/Game1.cs b/Source/Demos/Demo.TiledMaps/Game1.cs index ba451649..ac0e7057 100644 --- a/Source/Demos/Demo.TiledMaps/Game1.cs +++ b/Source/Demos/Demo.TiledMaps/Game1.cs @@ -6,7 +6,6 @@ using Microsoft.Xna.Framework.Input; using MonoGame.Extended; using MonoGame.Extended.BitmapFonts; using MonoGame.Extended.Graphics; -using MonoGame.Extended.Graphics.Effects; using MonoGame.Extended.Sprites; using MonoGame.Extended.Tiled; using MonoGame.Extended.ViewportAdapters; diff --git a/Source/MonoGame.Extended.Collisions/CollisionActor.cs b/Source/MonoGame.Extended.Collisions/CollisionActor.cs index 6bf57c96..1b50c2c7 100644 --- a/Source/MonoGame.Extended.Collisions/CollisionActor.cs +++ b/Source/MonoGame.Extended.Collisions/CollisionActor.cs @@ -1,5 +1,4 @@ using Microsoft.Xna.Framework; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.Collisions { diff --git a/Source/MonoGame.Extended.Collisions/CollisionGrid.cs b/Source/MonoGame.Extended.Collisions/CollisionGrid.cs index 79ce3cef..10303bb1 100644 --- a/Source/MonoGame.Extended.Collisions/CollisionGrid.cs +++ b/Source/MonoGame.Extended.Collisions/CollisionGrid.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.Collisions { diff --git a/Source/MonoGame.Extended.Collisions/CollisionGridCell.cs b/Source/MonoGame.Extended.Collisions/CollisionGridCell.cs index f30c1b58..ff79a2b4 100644 --- a/Source/MonoGame.Extended.Collisions/CollisionGridCell.cs +++ b/Source/MonoGame.Extended.Collisions/CollisionGridCell.cs @@ -1,4 +1,4 @@ -using MonoGame.Extended.Shapes; + namespace MonoGame.Extended.Collisions { diff --git a/Source/MonoGame.Extended.Collisions/CollisionWorld.cs b/Source/MonoGame.Extended.Collisions/CollisionWorld.cs index 9b25058b..5de88c13 100644 --- a/Source/MonoGame.Extended.Collisions/CollisionWorld.cs +++ b/Source/MonoGame.Extended.Collisions/CollisionWorld.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using Microsoft.Xna.Framework; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.Collisions { diff --git a/Source/MonoGame.Extended.Collisions/IActorTarget.cs b/Source/MonoGame.Extended.Collisions/IActorTarget.cs index db20078a..df93ea9e 100644 --- a/Source/MonoGame.Extended.Collisions/IActorTarget.cs +++ b/Source/MonoGame.Extended.Collisions/IActorTarget.cs @@ -1,5 +1,4 @@ using Microsoft.Xna.Framework; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.Collisions { diff --git a/Source/MonoGame.Extended.Content.Pipeline.Tiled/Graphics/TiledMapLayerModelContent.cs b/Source/MonoGame.Extended.Content.Pipeline.Tiled/Graphics/TiledMapLayerModelContent.cs index bc9b824e..cfb61daa 100644 --- a/Source/MonoGame.Extended.Content.Pipeline.Tiled/Graphics/TiledMapLayerModelContent.cs +++ b/Source/MonoGame.Extended.Content.Pipeline.Tiled/Graphics/TiledMapLayerModelContent.cs @@ -17,7 +17,7 @@ namespace MonoGame.Extended.Content.Pipeline.Graphics public string LayerName { get; } public IReadOnlyList Vertices { get; } public IReadOnlyList Indices { get; } - public Size ImageSize { get; } + public Size2 ImageSize { get; } public string TextureAssetName { get; } public TiledMapLayerModelContent(string layerName, TiledMapImageContent image) @@ -27,7 +27,7 @@ namespace MonoGame.Extended.Content.Pipeline.Graphics Vertices = new ReadOnlyCollection(_vertices); _indices = new List(); Indices = new ReadOnlyCollection(_indices); - ImageSize = new Size(image.Width, image.Height); + ImageSize = new Size2(image.Width, image.Height); TextureAssetName = Path.ChangeExtension(image.Source, null); } @@ -39,7 +39,7 @@ namespace MonoGame.Extended.Content.Pipeline.Graphics public void AddTileVertices(Point2 position, Rectangle? sourceRectangle = null, TiledMapTileFlipFlags flags = TiledMapTileFlipFlags.None) { float texelLeft, texelTop, texelRight, texelBottom; - var sourceRectangle1 = sourceRectangle ?? new Rectangle(0, 0, ImageSize.Width, ImageSize.Height); + var sourceRectangle1 = sourceRectangle ?? new Rectangle(0, 0, (int)ImageSize.Width, (int)ImageSize.Height); if (sourceRectangle.HasValue) { diff --git a/Source/MonoGame.Extended.Gui/Controls/GuiCheckBox.cs b/Source/MonoGame.Extended.Gui/Controls/GuiCheckBox.cs index dfbb50dd..91e424f9 100644 --- a/Source/MonoGame.Extended.Gui/Controls/GuiCheckBox.cs +++ b/Source/MonoGame.Extended.Gui/Controls/GuiCheckBox.cs @@ -59,7 +59,7 @@ namespace MonoGame.Extended.Gui.Controls protected override void DrawBackground(IGuiRenderer renderer, float deltaSeconds) { var boundingRectangle = BoundingRectangle; - var checkRectangle = new Rectangle(boundingRectangle.Location, BackgroundRegion.Size); + var checkRectangle = new Rectangle(boundingRectangle.X, boundingRectangle.Y, BackgroundRegion.Width, BackgroundRegion.Height); renderer.DrawRegion(BackgroundRegion, checkRectangle, Color); } diff --git a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiHorizontalSliderControl.cs b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiHorizontalSliderControl.cs index cd7a4ddc..10b46735 100644 --- a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiHorizontalSliderControl.cs +++ b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiHorizontalSliderControl.cs @@ -1,5 +1,4 @@ using Microsoft.Xna.Framework; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Controls.Desktop { diff --git a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiSliderControl.cs b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiSliderControl.cs index 44c98a6a..ec810a12 100644 --- a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiSliderControl.cs +++ b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiSliderControl.cs @@ -1,6 +1,5 @@ using System; using MonoGame.Extended.InputListeners; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Controls.Desktop { @@ -64,7 +63,7 @@ namespace MonoGame.Extended.NuclexGui.Controls.Desktop if (button == MouseButton.Left) { var thumbRegion = GetThumbRegion(); - if (thumbRegion.Contains(_pickupX, _pickupY)) + if (thumbRegion.Contains(new Point2(_pickupX, _pickupY))) { _pressedDown = true; @@ -98,7 +97,7 @@ namespace MonoGame.Extended.NuclexGui.Controls.Desktop _pickupY = y; } - _mouseOverThumb = GetThumbRegion().Contains(x, y); + _mouseOverThumb = GetThumbRegion().Contains(new Point2(x, y)); } /// diff --git a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiVerticalSliderControl.cs b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiVerticalSliderControl.cs index 55682bfc..3f3ded0d 100644 --- a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiVerticalSliderControl.cs +++ b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/GuiVerticalSliderControl.cs @@ -1,5 +1,4 @@ using Microsoft.Xna.Framework; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Controls.Desktop { diff --git a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IListRowLocator.cs b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IListRowLocator.cs index a3ee5e4e..aee5ed95 100644 --- a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IListRowLocator.cs +++ b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IListRowLocator.cs @@ -1,5 +1,4 @@ -using MonoGame.Extended.Shapes; - + namespace MonoGame.Extended.NuclexGui.Controls.Desktop { /// diff --git a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IOpeningLocator.cs b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IOpeningLocator.cs index 35fec6e6..2f453475 100644 --- a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IOpeningLocator.cs +++ b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IOpeningLocator.cs @@ -1,5 +1,4 @@ using Microsoft.Xna.Framework; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Controls.Desktop { diff --git a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IThumbLocator.cs b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IThumbLocator.cs index 528423f1..75348c19 100644 --- a/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IThumbLocator.cs +++ b/Source/MonoGame.Extended.NuclexGui/Controls/Desktop/IThumbLocator.cs @@ -1,5 +1,4 @@ -using MonoGame.Extended.Shapes; - + namespace MonoGame.Extended.NuclexGui.Controls.Desktop { /// diff --git a/Source/MonoGame.Extended.NuclexGui/Controls/GuiControl.cs b/Source/MonoGame.Extended.NuclexGui/Controls/GuiControl.cs index 9c0dd883..0094da9e 100644 --- a/Source/MonoGame.Extended.NuclexGui/Controls/GuiControl.cs +++ b/Source/MonoGame.Extended.NuclexGui/Controls/GuiControl.cs @@ -3,7 +3,6 @@ using System.Collections.ObjectModel; using Microsoft.Xna.Framework.Input; using MonoGame.Extended.InputListeners; using MonoGame.Extended.NuclexGui.Input; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Controls { diff --git a/Source/MonoGame.Extended.NuclexGui/Controls/GuiControlInput.cs b/Source/MonoGame.Extended.NuclexGui/Controls/GuiControlInput.cs index 071be3d9..bdfcf7ad 100644 --- a/Source/MonoGame.Extended.NuclexGui/Controls/GuiControlInput.cs +++ b/Source/MonoGame.Extended.NuclexGui/Controls/GuiControlInput.cs @@ -269,7 +269,7 @@ namespace MonoGame.Extended.NuclexGui.Controls var childBounds = control.Bounds.ToOffset(size.X, size.Y); // Is the mouse over this child? - if (childBounds.Contains(x, y)) + if (childBounds.Contains(new Point2(x, y))) { SwitchMouseOverControl(control); diff --git a/Source/MonoGame.Extended.NuclexGui/GuiScreen.cs b/Source/MonoGame.Extended.NuclexGui/GuiScreen.cs index dd89d151..7611a199 100644 --- a/Source/MonoGame.Extended.NuclexGui/GuiScreen.cs +++ b/Source/MonoGame.Extended.NuclexGui/GuiScreen.cs @@ -6,7 +6,6 @@ using MonoGame.Extended.InputListeners; using MonoGame.Extended.NuclexGui.Controls; using MonoGame.Extended.NuclexGui.Input; using MonoGame.Extended.NuclexGui.Support; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui { diff --git a/Source/MonoGame.Extended.NuclexGui/UniRectangle.cs b/Source/MonoGame.Extended.NuclexGui/UniRectangle.cs index 9016df3c..1fbd3b56 100644 --- a/Source/MonoGame.Extended.NuclexGui/UniRectangle.cs +++ b/Source/MonoGame.Extended.NuclexGui/UniRectangle.cs @@ -1,5 +1,4 @@ using Microsoft.Xna.Framework; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui { diff --git a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiGraphics.cs b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiGraphics.cs index e63d4828..a0e0e9b7 100644 --- a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiGraphics.cs +++ b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiGraphics.cs @@ -5,7 +5,6 @@ using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Visuals.Flat { diff --git a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiGraphicsDrawing.cs b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiGraphicsDrawing.cs index b6377f4d..3744079e 100644 --- a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiGraphicsDrawing.cs +++ b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiGraphicsDrawing.cs @@ -1,7 +1,6 @@ using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Visuals.Flat { diff --git a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiVisualizer.cs b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiVisualizer.cs index 24d320b8..f2145842 100644 --- a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiVisualizer.cs +++ b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/FlatGuiVisualizer.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Reflection; using Microsoft.Xna.Framework.Content; using MonoGame.Extended.NuclexGui.Controls; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Visuals.Flat { diff --git a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/IFlatGuiGraphics.cs b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/IFlatGuiGraphics.cs index c0dcfc04..11bacfe7 100644 --- a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/IFlatGuiGraphics.cs +++ b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/IFlatGuiGraphics.cs @@ -1,7 +1,6 @@ using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Visuals.Flat { diff --git a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatHorizontalSliderControlRenderer.cs b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatHorizontalSliderControlRenderer.cs index aa48d9b4..1407a625 100644 --- a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatHorizontalSliderControlRenderer.cs +++ b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatHorizontalSliderControlRenderer.cs @@ -1,5 +1,4 @@ using MonoGame.Extended.NuclexGui.Controls.Desktop; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Visuals.Flat.Renderers { diff --git a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatInputControlRenderer.cs b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatInputControlRenderer.cs index cbb083a3..4cc45f14 100644 --- a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatInputControlRenderer.cs +++ b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatInputControlRenderer.cs @@ -1,6 +1,5 @@ using Microsoft.Xna.Framework; using MonoGame.Extended.NuclexGui.Controls.Desktop; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Visuals.Flat.Renderers { diff --git a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatListControlRenderer.cs b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatListControlRenderer.cs index fea55049..026fe10b 100644 --- a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatListControlRenderer.cs +++ b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatListControlRenderer.cs @@ -1,6 +1,5 @@ using System; using MonoGame.Extended.NuclexGui.Controls.Desktop; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Visuals.Flat.Renderers { diff --git a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatVerticalSliderControlRenderer.cs b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatVerticalSliderControlRenderer.cs index 72c51e4e..d1975ad6 100644 --- a/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatVerticalSliderControlRenderer.cs +++ b/Source/MonoGame.Extended.NuclexGui/Visuals/Flat/Renderers/FlatVerticalSliderControlRenderer.cs @@ -1,5 +1,4 @@ using MonoGame.Extended.NuclexGui.Controls.Desktop; -using MonoGame.Extended.Shapes; namespace MonoGame.Extended.NuclexGui.Visuals.Flat.Renderers { diff --git a/Source/MonoGame.Extended.SceneGraphs/SceneGraph.cs b/Source/MonoGame.Extended.SceneGraphs/SceneGraph.cs index 7dd6a153..54393446 100644 --- a/Source/MonoGame.Extended.SceneGraphs/SceneGraph.cs +++ b/Source/MonoGame.Extended.SceneGraphs/SceneGraph.cs @@ -22,9 +22,9 @@ namespace MonoGame.Extended.SceneGraphs { var node = RootNode; - while ((node != null) && node.BoundingRectangle.Contains(x, y)) + while ((node != null) && node.BoundingRectangle.Contains(new Point2(x, y))) { - var childNode = node.Children.FirstOrDefault(c => c.BoundingRectangle.Contains(x, y)); + var childNode = node.Children.FirstOrDefault(c => c.BoundingRectangle.Contains(new Point2(x, y))); if (childNode != null) node = childNode; diff --git a/Source/MonoGame.Extended.SceneGraphs/SceneNode.cs b/Source/MonoGame.Extended.SceneGraphs/SceneNode.cs index 72e703f7..ce64d242 100644 --- a/Source/MonoGame.Extended.SceneGraphs/SceneNode.cs +++ b/Source/MonoGame.Extended.SceneGraphs/SceneNode.cs @@ -1,7 +1,6 @@ using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using MonoGame.Extended.Shapes; using MonoGame.Extended.Sprites; namespace MonoGame.Extended.SceneGraphs diff --git a/Source/MonoGame.Extended/BitmapFonts/BitmapFont.cs b/Source/MonoGame.Extended/BitmapFonts/BitmapFont.cs index 6d8cdf9e..57037817 100644 --- a/Source/MonoGame.Extended/BitmapFonts/BitmapFont.cs +++ b/Source/MonoGame.Extended/BitmapFonts/BitmapFont.cs @@ -31,13 +31,13 @@ namespace MonoGame.Extended.BitmapFonts return char.IsLowSurrogate(s, index) ? 0 : char.ConvertToUtf32(s, index); } - public Size MeasureString(string text) + public Size2 MeasureString(string text) { if (string.IsNullOrEmpty(text)) - return Size.Empty; + return Size2.Empty; var stringRectangle = GetStringRectangle(text, Point.Zero); - return new Size(stringRectangle.Width, stringRectangle.Height); + return new Size2(stringRectangle.Width, stringRectangle.Height); } public Rectangle GetStringRectangle(string text, Vector2 position) diff --git a/Source/MonoGame.Extended/BoundingRectangle.cs b/Source/MonoGame.Extended/BoundingRectangle.cs index 092faf00..4f28569c 100644 --- a/Source/MonoGame.Extended/BoundingRectangle.cs +++ b/Source/MonoGame.Extended/BoundingRectangle.cs @@ -24,31 +24,37 @@ namespace MonoGame.Extended /// /// /// - [DebuggerDisplay("{DebugDisplayString,nq}")] + [DebuggerDisplay("{" + nameof(DebugDisplayString) + ",nq}")] public struct BoundingRectangle : IEquatable, IEquatableByRef { /// - /// The centre position of this . + /// The with and + /// set to . /// - public Point2 Centre; + public static readonly BoundingRectangle Empty = new BoundingRectangle(); /// - /// The distance from the point along both axes to any point on the boundary of this + /// The centre position of this . + /// + public Point2 Center; + + /// + /// The distance from the point along both axes to any point on the boundary of this /// . /// - public Vector2 Radii; + public Vector2 HalfExtents; /// /// Initializes a new instance of the structure from the specified centre /// and the radii . /// - /// The centre . - /// The radii . - public BoundingRectangle(Point2 centre, Vector2 radii) + /// The centre . + /// The radii . + public BoundingRectangle(Point2 center, Size2 halfExtents) { - Centre = centre; - Radii = radii; + Center = center; + HalfExtents = halfExtents; } /// @@ -57,38 +63,77 @@ namespace MonoGame.Extended /// /// The minimum point. /// The maximum point. - /// An . + /// The resulting bounding rectangle. + public static void CreateFrom(Point2 minimum, Point2 maximum, out BoundingRectangle result) + { + result.Center = new Point2((maximum.X + minimum.X) * 0.5f, (maximum.Y + minimum.Y) * 0.5f); + result.HalfExtents = new Vector2((maximum.X - minimum.X) * 0.5f, (maximum.Y - minimum.Y) * 0.5f); + } + + /// + /// Computes the from a minimum and maximum + /// . + /// + /// The minimum point. + /// The maximum point. + /// The resulting . public static BoundingRectangle CreateFrom(Point2 minimum, Point2 maximum) { - var centre = new Point2((maximum.X + minimum.X)*0.5f, (maximum.Y + minimum.Y)*0.5f); - var radii = new Vector2((maximum.X - minimum.X)*0.5f, (maximum.Y - minimum.Y)*0.5f); - return new BoundingRectangle(centre, radii); + BoundingRectangle result; + CreateFrom(minimum, maximum, out result); + return result; } /// /// Computes the from a list of structures. /// /// The points. - /// An . + /// The resulting bounding rectangle. + public static void CreateFrom(IReadOnlyList points, out BoundingRectangle result) + { + Point2 minimum; + Point2 maximum; + PrimitivesHelper.CreateRectangleFromPoints(points, out minimum, out maximum); + CreateFrom(minimum, maximum, out result); + } + + /// + /// Computes the from a list of structures. + /// + /// The points. + /// The resulting . public static BoundingRectangle CreateFrom(IReadOnlyList points) { - // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 4.2; Bounding Volumes - Axis-aligned Bounding Boxes (AABBs). pg 82-84 + BoundingRectangle result; + CreateFrom(points, out result); + return result; + } - if ((points == null) || (points.Count == 0)) - return new BoundingRectangle(); - - var minimum = new Vector2(float.MaxValue); - var maximum = new Vector2(float.MinValue); - - // ReSharper disable once ForCanBeConvertedToForeach - for (var index = 0; index < points.Count; ++index) - { - var point = points[index]; - minimum = Point2.Minimum(minimum, point); - maximum = Point2.Maximum(maximum, point); - } - - return CreateFrom(minimum, maximum); + /// + /// Computes the from the specified transformed by + /// the + /// specified . + /// + /// The bounding rectangle. + /// The transform matrix. + /// The resulting bounding rectangle. + /// + /// The from the transformed by the + /// . + /// + /// + /// + /// If a transformed is used for then the + /// resulting will have the compounded transformation, which most likely is + /// not desired. + /// + /// + public static void Transform(ref BoundingRectangle boundingRectangle, + ref Matrix2D transformMatrix, out BoundingRectangle result) + { + PrimitivesHelper.TransformRectangle(ref boundingRectangle.Center, ref boundingRectangle.HalfExtents, ref transformMatrix); + result.Center = boundingRectangle.Center; + result.HalfExtents = boundingRectangle.HalfExtents; } /// @@ -109,18 +154,35 @@ namespace MonoGame.Extended /// not desired. /// /// - public static BoundingRectangle CreateFrom(BoundingRectangle boundingRectangle, + public static BoundingRectangle Transform(BoundingRectangle boundingRectangle, ref Matrix2D transformMatrix) { - // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 4.2; Bounding Volumes - Axis-aligned Bounding Boxes (AABBs). pg 86-87 + BoundingRectangle result; + Transform(ref boundingRectangle, ref transformMatrix, out result); + return result; + } - var centre = transformMatrix.Transform(boundingRectangle.Centre); - var radii = boundingRectangle.Radii; - radii.X = radii.X*Math.Abs(transformMatrix.M11) + radii.X*Math.Abs(transformMatrix.M12) + - radii.X*Math.Abs(transformMatrix.M31); - radii.Y = radii.Y*Math.Abs(transformMatrix.M21) + radii.Y*Math.Abs(transformMatrix.M22) + - radii.Y*Math.Abs(transformMatrix.M32); - return new BoundingRectangle(centre, radii); + /// + /// Computes the that contains the two specified + /// structures. + /// + /// The first bounding rectangle. + /// The second bounding rectangle. + /// The resulting bounding rectangle that contains both the and the + /// . + public static void Union(ref BoundingRectangle first, ref BoundingRectangle second, out BoundingRectangle result) + { + // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 6.5; Bounding Volume Hierarchies - Merging Bounding Volumes. pg 267 + + var firstMinimum = first.Center - first.HalfExtents; + var firstMaximum = first.Center + first.HalfExtents; + var secondMinimum = second.Center - second.HalfExtents; + var secondMaximum = second.Center + second.HalfExtents; + + var minimum = Point2.Minimum(firstMinimum, secondMinimum); + var maximum = Point2.Maximum(firstMaximum, secondMaximum); + + result = CreateFrom(minimum, maximum); } /// @@ -130,22 +192,14 @@ namespace MonoGame.Extended /// The first bounding rectangle. /// The second bounding rectangle. /// - /// An that contains both the and the + /// A that contains both the and the /// . /// public static BoundingRectangle Union(BoundingRectangle first, BoundingRectangle second) { - // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 6.5; Bounding Volume Hierarchies - Merging Bounding Volumes. pg 267 - - var firstMinimum = first.Centre - first.Radii; - var firstMaximum = first.Centre + first.Radii; - var secondMinimum = second.Centre - second.Radii; - var secondMaximum = second.Centre + second.Radii; - - var minimum = Point2.Minimum(firstMinimum, secondMinimum); - var maximum = Point2.Maximum(firstMaximum, secondMaximum); - - return CreateFrom(minimum, maximum); + BoundingRectangle result; + Union(ref first, ref second, out result); + return result; } /// @@ -154,7 +208,7 @@ namespace MonoGame.Extended /// /// The bounding rectangle. /// - /// An that contains both the and + /// A that contains both the and /// this /// . /// @@ -164,41 +218,46 @@ namespace MonoGame.Extended } /// - /// Computes the that is in common between the two specified + /// Computes the that is in common between the two specified /// structures. /// /// The first bounding rectangle. /// The second bounding rectangle. - /// - /// An that is in common between both the and - /// the , if they intersect; otherwise, null. - /// - public static BoundingRectangle? Intersection(BoundingRectangle first, - BoundingRectangle second) + /// The resulting bounding rectangle that is in common between both the and + /// the , if they intersect; otherwise, . + public static void Intersection(ref BoundingRectangle first, + ref BoundingRectangle second, out BoundingRectangle result) { - var firstMinimum = first.Centre - first.Radii; - var firstMaximum = first.Centre + first.Radii; - var secondMinimum = second.Centre - second.Radii; - var secondMaximum = second.Centre + second.Radii; + var firstMinimum = first.Center - first.HalfExtents; + var firstMaximum = first.Center + first.HalfExtents; + var secondMinimum = second.Center - second.HalfExtents; + var secondMaximum = second.Center + second.HalfExtents; var minimum = Point2.Maximum(firstMinimum, secondMinimum); var maximum = Point2.Minimum(firstMaximum, secondMaximum); if ((maximum.X < minimum.X) || (maximum.Y < minimum.Y)) - return null; - - return CreateFrom(minimum, maximum); + result = new BoundingRectangle(); + else + result = CreateFrom(minimum, maximum); } /// - /// Updates this from a list of structures. + /// Computes the that is in common between the two specified + /// structures. /// - /// The points. - public void UpdateFromPoints(IReadOnlyList points) + /// The first bounding rectangle. + /// The second bounding rectangle. + /// + /// A that is in common between both the and + /// the , if they intersect; otherwise, . + /// + public static BoundingRectangle Intersection(BoundingRectangle first, + BoundingRectangle second) { - var boundingRectangle = CreateFrom(points); - Centre = boundingRectangle.Centre; - Radii = boundingRectangle.Radii; + BoundingRectangle result; + Intersection(ref first, ref second, out result); + return result; } /// @@ -207,12 +266,31 @@ namespace MonoGame.Extended /// /// The bounding rectangle. /// - /// An that is in common between the specified - /// and this . + /// A that is in common between both the and + /// this , if they intersect; otherwise, . /// - public BoundingRectangle? Intersection(BoundingRectangle boundingRectangle) + public BoundingRectangle Intersection(BoundingRectangle boundingRectangle) { - return Intersection(this, boundingRectangle); + BoundingRectangle result; + Intersection(ref this, ref boundingRectangle, out result); + return result; + } + + /// + /// Determines whether the two specified structures intersect. + /// + /// The first bounding rectangle. + /// The second bounding rectangle. + /// + /// true if the intersects with the ; otherwise, false. + /// + public static bool Intersects(ref BoundingRectangle first, ref BoundingRectangle second) + { + // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 4.2; Bounding Volumes - Axis-aligned Bounding Boxes (AABBs). pg 80 + + var distance = first.Center - second.Center; + var radii = first.HalfExtents + second.HalfExtents; + return Math.Abs(distance.X) <= radii.X && Math.Abs(distance.Y) <= radii.Y; } /// @@ -225,11 +303,22 @@ namespace MonoGame.Extended /// public static bool Intersects(BoundingRectangle first, BoundingRectangle second) { - // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 4.2; Bounding Volumes - Axis-aligned Bounding Boxes (AABBs). pg 80 + return Intersects(ref first, ref second); + } - var distance = first.Centre - second.Centre; - var radii = first.Radii + second.Radii; - return (Math.Abs(distance.X) <= radii.X) && (Math.Abs(distance.Y) <= radii.Y); + /// + /// Determines whether the specified intersects with this + /// . + /// + /// The bounding rectangle. + /// + /// true if the intersects with this + /// ; otherwise, + /// false. + /// + public bool Intersects(ref BoundingRectangle boundingRectangle) + { + return Intersects(ref this, ref boundingRectangle); } /// @@ -244,7 +333,38 @@ namespace MonoGame.Extended /// public bool Intersects(BoundingRectangle boundingRectangle) { - return Intersects(this, boundingRectangle); + return Intersects(ref this, ref boundingRectangle); + } + + /// + /// Updates this from a list of structures. + /// + /// The points. + public void UpdateFromPoints(IReadOnlyList points) + { + var boundingRectangle = CreateFrom(points); + Center = boundingRectangle.Center; + HalfExtents = boundingRectangle.HalfExtents; + } + + /// + /// Determines whether the specified contains the specified + /// . + /// + /// The bounding rectangle. + /// The point. + /// + /// true if the contains the ; otherwise, + /// false. + /// + public static bool Contains(ref BoundingRectangle boundingRectangle, ref Point2 point) + { + // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 4.2; Bounding Volumes - Axis-aligned Bounding Boxes (AABBs). pg 78 + + var distance = boundingRectangle.Center - point; + var radii = boundingRectangle.HalfExtents; + + return (Math.Abs(distance.X) <= radii.X) && (Math.Abs(distance.Y) <= radii.Y); } /// @@ -259,12 +379,7 @@ namespace MonoGame.Extended /// public static bool Contains(BoundingRectangle boundingRectangle, Point2 point) { - // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 4.2; Bounding Volumes - Axis-aligned Bounding Boxes (AABBs). pg 78 - - var distance = boundingRectangle.Centre - point; - var radii = boundingRectangle.Radii; - - return (Math.Abs(distance.X) <= radii.X) && (Math.Abs(distance.Y) <= radii.Y); + return Contains(ref boundingRectangle, ref point); } /// @@ -280,6 +395,15 @@ namespace MonoGame.Extended return Contains(this, point); } + /// + /// Computes the squared distance from this to a . + /// + /// The point. + /// The squared distance from this to the . + public float SquaredDistanceTo(Point2 point) + { + return PrimitivesHelper.SquaredDistanceToPointFromRectangle(Center - HalfExtents, Center + HalfExtents, point); + } /// /// Computes the closest on this to a specified @@ -289,41 +413,20 @@ namespace MonoGame.Extended /// The closest on this to the . public Point2 ClosestPointTo(Point2 point) { - // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 5.1.2; Basic Primitive Tests - Closest-point Computations. pg 130-131 - - var minimum = Centre - Radii; - var maximum = Centre + Radii; - var result = point; - - // For each coordinate axis, if the point coordinate value is outside box, clamp it to the box, else keep it as is - if (result.X < minimum.X) - result.X = minimum.X; - else - { - if (result.X > maximum.X) - result.X = maximum.X; - } - - if (result.Y < minimum.Y) - result.Y = minimum.Y; - else - { - if (result.Y > maximum.Y) - result.Y = maximum.Y; - } - + Point2 result; + PrimitivesHelper.ClosestPointToPointFromRectangle(Center - HalfExtents, Center + HalfExtents, point, out result); return result; } /// /// Compares two structures. The result specifies whether the values of the - /// and fields of the two structures + /// and fields of the two structures /// are equal. /// /// The first bounding rectangle. /// The second bounding rectangle. /// - /// true if the and fields of the two + /// true if the and fields of the two /// structures are equal; otherwise, false. /// public static bool operator ==(BoundingRectangle first, BoundingRectangle second) @@ -331,6 +434,22 @@ namespace MonoGame.Extended return first.Equals(ref second); } + /// + /// Compares two structures. The result specifies whether the values of the + /// and fields of the two structures + /// are unequal. + /// + /// The first bounding rectangle. + /// The second bounding rectangle. + /// + /// true if the and fields of the two + /// structures are unequal; otherwise, false. + /// + public static bool operator !=(BoundingRectangle first, BoundingRectangle second) + { + return !(first == second); + } + /// /// Indicates whether this is equal to another /// . @@ -356,7 +475,7 @@ namespace MonoGame.Extended /// public bool Equals(ref BoundingRectangle boundingRectangle) { - return (boundingRectangle.Centre == Centre) && (boundingRectangle.Radii == Radii); + return (boundingRectangle.Center == Center) && (boundingRectangle.HalfExtents == HalfExtents); } /// @@ -369,26 +488,10 @@ namespace MonoGame.Extended public override bool Equals(object obj) { if (obj is BoundingRectangle) - return Equals((BoundingRectangle) obj); + return Equals((BoundingRectangle)obj); return false; } - /// - /// Compares two structures. The result specifies whether the values of the - /// and fields of the two structures - /// are unequal. - /// - /// The first bounding box. - /// The second bounding box. - /// - /// true if the and fields of the two - /// structures are unequal; otherwise, false. - /// - public static bool operator !=(BoundingRectangle first, BoundingRectangle second) - { - return !(first == second); - } - /// /// Returns a hash code of this suitable for use in hashing algorithms and data /// structures like a hash table. @@ -400,7 +503,7 @@ namespace MonoGame.Extended { unchecked { - return (Centre.GetHashCode()*397) ^ Radii.GetHashCode(); + return (Center.GetHashCode() * 397) ^ HalfExtents.GetHashCode(); } } @@ -413,7 +516,7 @@ namespace MonoGame.Extended /// public static implicit operator BoundingRectangle(Rectangle rectangle) { - var radii = new Size2(rectangle.Width/2f, rectangle.Height/2f); + var radii = new Size2(rectangle.Width * 0.5f, rectangle.Height * 0.5f); var centre = new Point2(rectangle.X + radii.Width, rectangle.Y + radii.Height); return new BoundingRectangle(centre, radii); } @@ -427,9 +530,37 @@ namespace MonoGame.Extended /// public static implicit operator Rectangle(BoundingRectangle boundingRectangle) { - var minimum = boundingRectangle.Centre - boundingRectangle.Radii; - return new Rectangle((int) minimum.X, (int) minimum.Y, (int) boundingRectangle.Radii.X*2, - (int) boundingRectangle.Radii.Y*2); + var minimum = boundingRectangle.Center - boundingRectangle.HalfExtents; + return new Rectangle((int)minimum.X, (int)minimum.Y, (int)boundingRectangle.HalfExtents.X * 2, + (int)boundingRectangle.HalfExtents.Y * 2); + } + + /// + /// Performs an implicit conversion from a to a . + /// + /// The rectangle. + /// + /// The resulting . + /// + public static implicit operator BoundingRectangle(RectangleF rectangle) + { + var radii = new Size2(rectangle.Width * 0.5f, rectangle.Height * 0.5f); + var centre = new Point2(rectangle.X + radii.Width, rectangle.Y + radii.Height); + return new BoundingRectangle(centre, radii); + } + + /// + /// Performs an implicit conversion from a to a . + /// + /// The bounding rectangle. + /// + /// The resulting . + /// + public static implicit operator RectangleF(BoundingRectangle boundingRectangle) + { + var minimum = boundingRectangle.Center - boundingRectangle.HalfExtents; + return new RectangleF(minimum.X, minimum.Y, boundingRectangle.HalfExtents.X * 2, + boundingRectangle.HalfExtents.Y * 2); } /// @@ -440,7 +571,7 @@ namespace MonoGame.Extended /// public override string ToString() { - return $"Centre: {Centre}, Radii: {Radii}"; + return $"Centre: {Center}, Radii: {HalfExtents}"; } internal string DebugDisplayString => ToString(); diff --git a/Source/MonoGame.Extended/Camera2D.cs b/Source/MonoGame.Extended/Camera2D.cs index fc0bbafc..dea3ab2b 100644 --- a/Source/MonoGame.Extended/Camera2D.cs +++ b/Source/MonoGame.Extended/Camera2D.cs @@ -1,7 +1,6 @@ using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using MonoGame.Extended.Shapes; using MonoGame.Extended.ViewportAdapters; namespace MonoGame.Extended diff --git a/Source/MonoGame.Extended/CircleF.cs b/Source/MonoGame.Extended/CircleF.cs new file mode 100644 index 00000000..6bab4f23 --- /dev/null +++ b/Source/MonoGame.Extended/CircleF.cs @@ -0,0 +1,497 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using Microsoft.Xna.Framework; + +namespace MonoGame.Extended +{ + // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 4.3; Bounding Volumes - Spheres. pg 88 + + /// + /// A two dimensional circle defined by a centre and a radius . + /// + /// + /// + /// An is categorized by the set of all points in a plane that are at equal distance from + /// the + /// centre. + /// + /// + /// + /// + [DataContract] + public struct CircleF : IEquatable, IEquatableByRef + { + /// + /// The centre position of this . + /// + [DataMember] public Point2 Center; + + /// + /// The distance from the point to any point on the boundary of this . + /// + [DataMember] public float Radius; + + /// + /// Gets the distance from a point to the opposite point, both on the boundary of this . + /// + public float Diameter => 2 * Radius; + + /// + /// Gets the distance around the boundary of this . + /// + public float Circumference => 2 * MathHelper.Pi * Radius; + + /// + /// Initializes a new instance of the structure from the specified centre + /// and the radius . + /// + /// The centre point. + /// The radius. + public CircleF(Point2 center, float radius) + { + Center = center; + Radius = radius; + } + + /// + /// Computes the bounding from a minimum and maximum + /// . + /// + /// The minimum point. + /// The maximum point. + /// The resulting circle. + public static void CreateFrom(Point2 minimum, Point2 maximum, out CircleF result) + { + result.Center = new Point2((maximum.X + minimum.X) * 0.5f, (maximum.Y + minimum.Y) * 0.5f); + var distanceVector = maximum - minimum; + result.Radius = distanceVector.X > distanceVector.Y ? distanceVector.X * 0.5f : distanceVector.Y * 0.5f; + } + + /// + /// Computes the bounding from a minimum and maximum + /// . + /// + /// The minimum point. + /// The maximum point. + /// An . + public static CircleF CreateFrom(Point2 minimum, Point2 maximum) + { + CircleF result; + CreateFrom(minimum, maximum, out result); + return result; + } + + /// + /// Computes the bounding from a list of structures. + /// + /// The points. + /// The resulting circle. + public static void CreateFrom(IReadOnlyList points, out CircleF result) + { + // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 4.3; Bounding Volumes - Spheres. pg 89-90 + + if (points == null || points.Count == 0) + { + result = default(CircleF); + return; + } + + var minimum = new Point2(float.MaxValue, float.MaxValue); + var maximum = new Point2(float.MinValue, float.MinValue); + + // ReSharper disable once ForCanBeConvertedToForeach + for (var index = points.Count - 1; index >= 0; --index) + { + var point = points[index]; + minimum = Point2.Minimum(minimum, point); + maximum = Point2.Maximum(maximum, point); + } + + CreateFrom(minimum, maximum, out result); + } + + /// + /// Computes the bounding from a list of structures. + /// + /// The points. + /// An . + public static CircleF CreateFrom(IReadOnlyList points) + { + CircleF result; + CreateFrom(points, out result); + return result; + } + + /// + /// Determines whether the two specified structures intersect. + /// + /// The first circle. + /// The second circle. + /// + /// true if the intersects with the ; otherwise, false. + /// + public static bool Intersects(ref CircleF first, ref CircleF second) + { + // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 4.3; Bounding Volumes - Spheres. pg 88 + + // Calculate squared distance between centers + var distanceVector = first.Center - second.Center; + var distanceSquared = distanceVector.Dot(distanceVector); + var radiusSum = first.Radius + second.Radius; + return distanceSquared <= radiusSum * radiusSum; + } + + /// + /// Determines whether the two specified structures intersect. + /// + /// The first circle. + /// The second circle. + /// + /// true if the intersects with the ; otherwise, false. + /// + public static bool Intersects(CircleF first, CircleF second) + { + return Intersects(ref first, ref second); + } + + /// + /// Determines whether the specified intersects with this . + /// + /// The circle. + /// + /// true if the intersects with this ; otherwise, + /// false. + /// + public bool Intersects(ref CircleF circle) + { + return Intersects(ref this, ref circle); + } + + /// + /// Determines whether the specified intersects with this . + /// + /// The circle. + /// + /// true if the intersects with this ; otherwise, + /// false. + /// + public bool Intersects(CircleF circle) + { + return Intersects(ref this, ref circle); + } + + /// + /// Determines whether the specified and structures intersect. + /// + /// The circle. + /// The rectangle. + /// + /// true if the intersects with the ; otherwise, false + /// . + /// + public static bool Intersects(ref CircleF circle, ref BoundingRectangle rectangle) + { + // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 5.25; Basic Primitives Test - Testing Sphere Against AABB. pg 165-166 + + // Compute squared distance between sphere center and AABB boundary + var distanceSquared = rectangle.SquaredDistanceTo(circle.Center); + // Circle and AABB intersect if the (squared) distance between the AABB's boundary and the circle is less than the (squared) circle's radius + return distanceSquared <= circle.Radius * circle.Radius; + } + + /// + /// Determines whether the specified and structures intersect. + /// + /// The circle. + /// The rectangle. + /// + /// true if the intersects with the ; otherwise, false + /// . + /// + public static bool Intersects(CircleF circle, BoundingRectangle rectangle) + { + return Intersects(ref circle, ref rectangle); + } + + /// + /// Determines whether the specified intersects with this . + /// + /// The rectangle. + /// + /// true if the intersects with this ; otherwise, + /// false. + /// + public bool Intersects(ref BoundingRectangle rectangle) + { + return Intersects(ref this, ref rectangle); + } + + /// + /// Determines whether the specified intersects with this . + /// + /// The rectangle. + /// + /// true if the intersects with this ; otherwise, + /// false. + /// + public bool Intersects(BoundingRectangle rectangle) + { + return Intersects(ref this, ref rectangle); + } + + /// + /// Determines whether the specified contains the specified + /// . + /// + /// The circle. + /// The point. + /// + /// true if the contains the ; otherwise, + /// false. + /// + public static bool Contains(ref CircleF circle, Point2 point) + { + var distance = circle.Center - point; + return Math.Abs(distance.X) <= circle.Radius && Math.Abs(distance.Y) <= circle.Radius; + } + + /// + /// Determines whether the specified contains the specified + /// . + /// + /// The circle. + /// The point. + /// + /// true if the contains the ; otherwise, + /// false. + /// + public static bool Contains(CircleF circle, Point2 point) + { + return Contains(ref circle, point); + } + + /// + /// Determines whether this contains the specified . + /// + /// The point. + /// + /// true if this contains the ; otherwise, + /// false. + /// + public bool Contains(Point2 point) + { + return Contains(ref this, point); + } + + /// + /// Computes the closest on this to a specified + /// . + /// + /// The point. + /// The closest on this to the . + public Point2 ClosestPointTo(Point2 point) + { + var distanceVector = point - Center; + var lengthSquared = distanceVector.Dot(distanceVector); + if (lengthSquared <= Radius * Radius) + return point; + distanceVector.Normalize(); + return Center + Radius * distanceVector; + } + + /// + /// Computes the on the boundary of of this using the specified angle. + /// + /// The angle in radians. + /// The on the boundary of this using . + public Point2 BoundaryPointAt(float angle) + { + var direction = new Vector2((float) Math.Cos(angle), (float) Math.Sin(angle)); + return Center + Radius * direction; + } + + [Obsolete("Circle.GetPointAlongEdge() may be removed in the future. Use BoundaryPointAt() instead.")] + public Point2 GetPointAlongEdge(float angle) + { + return Center + new Vector2(Radius * (float) Math.Cos(angle), Radius * (float) Math.Sin(angle)); + } + + /// + /// Compares two structures. The result specifies whether the values of the + /// and fields of the two structures + /// are equal. + /// + /// The first circle. + /// The second circle. + /// + /// true if the and fields of the two + /// structures are equal; otherwise, false. + /// + public static bool operator ==(CircleF first, CircleF second) + { + return first.Equals(ref second); + } + + /// + /// Compares two structures. The result specifies whether the values of the + /// and fields of the two structures + /// are unequal. + /// + /// The first circle. + /// The second circle. + /// + /// true if the and fields of the two + /// structures are unequal; otherwise, false. + /// + public static bool operator !=(CircleF first, CircleF second) + { + return !(first == second); + } + + /// + /// Indicates whether this is equal to another . + /// + /// The circle. + /// + /// true if this is equal to the ; otherwise, false. + /// + public bool Equals(CircleF circle) + { + return Equals(ref circle); + } + + /// + /// Indicates whether this is equal to another . + /// + /// The bounding rectangle. + /// + /// true if this is equal to the ; + /// otherwise,false. + /// + public bool Equals(ref CircleF circle) + { + // ReSharper disable once CompareOfFloatsByEqualityOperator + return circle.Center == Center && circle.Radius == Radius; + } + + /// + /// Returns a value indicating whether this is equal to a specified object. + /// + /// The object to make the comparison with. + /// + /// true if this is equal to ; otherwise, false. + /// + public override bool Equals(object obj) + { + return obj is CircleF && Equals((CircleF) obj); + } + + /// + /// Returns a hash code of this suitable for use in hashing algorithms and data + /// structures like a hash table. + /// + /// + /// A hash code of this . + /// + public override int GetHashCode() + { + unchecked + { + return (Center.GetHashCode() * 397) ^ Radius.GetHashCode(); + } + } + + /// + /// Performs an implicit conversion from a to a . + /// + /// The circle. + /// + /// The resulting . + /// + public static implicit operator Rectangle(CircleF circle) + { + var diameter = (int) circle.Diameter; + return new Rectangle((int) (circle.Center.X - circle.Radius), (int) (circle.Center.Y - circle.Radius), + diameter, diameter); + } + + /// + /// Performs a conversion from a specified to a . + /// + /// + /// The resulting . + /// + public Rectangle ToRectangle() + { + return this; + } + + /// + /// Performs an implicit conversion from a to a . + /// + /// The rectangle. + /// + /// The resulting . + /// + public static implicit operator CircleF(Rectangle rectangle) + { + var halfWidth = rectangle.Width / 2; + var halfHeight = rectangle.Height / 2; + return new CircleF(new Point2(rectangle.X + halfWidth, rectangle.Y + halfHeight), + halfWidth > halfHeight ? halfWidth : halfHeight); + } + + /// + /// Performs an implicit conversion from a to a . + /// + /// The circle. + /// + /// The resulting . + /// + public static implicit operator RectangleF(CircleF circle) + { + var diameter = circle.Diameter; + return new RectangleF(circle.Center.X - circle.Radius, circle.Center.Y - circle.Radius, diameter, diameter); + } + + /// + /// Performs a conversion from a specified to a . + /// + /// + /// The resulting . + /// + public RectangleF ToRectangleF() + { + return this; + } + + /// + /// Performs an implicit conversion from a to a . + /// + /// The rectangle. + /// + /// The resulting . + /// + public static implicit operator CircleF(RectangleF rectangle) + { + var halfWidth = rectangle.Width * 0.5f; + var halfHeight = rectangle.Height * 0.5f; + return new CircleF(new Point2(rectangle.X + halfWidth, rectangle.Y + halfHeight), + halfWidth > halfHeight ? halfWidth : halfHeight); + } + + /// + /// Returns a that represents this . + /// + /// + /// A that represents this . + /// + public override string ToString() + { + return $"Centre: {Center}, Radius: {Radius}"; + } + + internal string DebugDisplayString => ToString(); + } +} diff --git a/Source/MonoGame.Extended/Shapes/EllipseF.cs b/Source/MonoGame.Extended/EllipseF.cs similarity index 94% rename from Source/MonoGame.Extended/Shapes/EllipseF.cs rename to Source/MonoGame.Extended/EllipseF.cs index eb097452..8676bcbb 100644 --- a/Source/MonoGame.Extended/Shapes/EllipseF.cs +++ b/Source/MonoGame.Extended/EllipseF.cs @@ -1,9 +1,9 @@ using System; using Microsoft.Xna.Framework; -namespace MonoGame.Extended.Shapes +namespace MonoGame.Extended { - public class EllipseF : IShapeF + public class EllipseF { public EllipseF(Vector2 center, float radiusX, float radiusY) { diff --git a/Source/MonoGame.Extended/IRectangular.cs b/Source/MonoGame.Extended/IRectangular.cs index e8fe0ee7..719d6757 100644 --- a/Source/MonoGame.Extended/IRectangular.cs +++ b/Source/MonoGame.Extended/IRectangular.cs @@ -1,5 +1,4 @@ -using MonoGame.Extended.Shapes; - + namespace MonoGame.Extended { public interface IRectangular diff --git a/Source/MonoGame.Extended/ISizable.cs b/Source/MonoGame.Extended/ISizable.cs index 5db0a848..5b55058e 100644 --- a/Source/MonoGame.Extended/ISizable.cs +++ b/Source/MonoGame.Extended/ISizable.cs @@ -1,4 +1,5 @@ -namespace MonoGame.Extended + +namespace MonoGame.Extended { public interface ISizable { diff --git a/Source/MonoGame.Extended/MonoGame.Extended.csproj b/Source/MonoGame.Extended/MonoGame.Extended.csproj index 6c3c9038..438c7a56 100644 --- a/Source/MonoGame.Extended/MonoGame.Extended.csproj +++ b/Source/MonoGame.Extended/MonoGame.Extended.csproj @@ -49,14 +49,14 @@ - + - - + + @@ -125,13 +125,11 @@ - - - - - - - + + + + + @@ -167,6 +165,7 @@ +