craftworkgames / MonoGame.Extended

Extensions to make MonoGame more awesome
http://www.monogameextended.net/
Other
1.42k stars 324 forks source link

Missing collision for diffrent shapes, line, circle, polygon #592

Open EnemyArea opened 5 years ago

EnemyArea commented 5 years ago

Is there any plan when this could get implemented?

lithiumtoast commented 5 years ago

Which collision tests are you looking for exactly? I could do a PR in combination with #590. (I wrote the current collision tests such as Segment2, Ray2, BoundingRectangle, etc).

EnemyArea commented 5 years ago

To be more exact: Lines/slopes and circles. Rectangles are nice to have, same as rotated polygons :) I have a Tilemap which I outlined with slopes to get some hitboxes for collision areas. I currently use the Aether.Physics2D for that, but I don't need that compleye physics, just the collisions. My characters are circles which has to collide with each other and the tilemap.

lithiumtoast commented 5 years ago

Line-to-circle and line-to-triangle if not already implemented is pretty easy. Oriented-bounding-boxes (rotated rectangles) is a bit tricky but what I remember is to transform one into the space of another so it becomes axis-aligned-bounding-box-to-oriented-bounding-box (AABB-to-OBB). It would probably require that the signature of the method would take one or two transformation matrices. Same for polygon-to-polygon, transform one polygon into the space of the another polygon then use seperating-axis-theorem (SAT). Where I got stuck last time was wrestling with the idea of vertices for rendering and collision. I tried and failed with the idea of having the two being the same. It's too complicated to have a data structure keep the two in unison and ultimately progresses into an engine which can easily slide down the slippery slope to something like a physics engine.

lithiumtoast commented 5 years ago

@EnemyArea I'll look into some preposing some method signatures.

@craftworkgames For this I would probably re-visit Polygon and Polyline and need to discuss the Shapes namespace with you.

craftworkgames commented 5 years ago

@lithiumtoast no problem. What did you have in mind?

Now that I've published version 3.6-beta to NuGet.org I think we should take this opportunity to start cleaning some things up.

I can think of 3 ways to go:

  1. We could do something like LibGDX and put all of the shapes and other mathy classes into a MonoGame.Extended.Math namespace.

  2. We could keep the Shapes namespace and gather up all the shapes that aren't currently in there (e.g. CircleF and EllipseF).

  3. We could move the shapes back out into the root MonoGame.Extended namespace.

  4. I'm open to other ideas???

On one hand I feel like the first 2 options are more organized but on the other hand MonoGame has it's Rectangle class in the root namespace Microsoft.Xna.Framework.

lithiumtoast commented 5 years ago

I honestly hate how the decision made in XNA's time (+10 years) to have BoundingBox, BoundingSphere, Rectangle, RectangleF, etc, in the root directory still has influence today. Re-visiting MonoGame I find it ungodly how there is just so much code in one directory. It makes it hard to reason about the modules of code, such as which classes or structs are interconnected or possibly interconnected, without opening the files and analyzing the code itself. MonoGame.Extended is showing similiar problems now too as the core package grows. Did I mention I'm thinking to add TriangleF and all the XyzD for doubles and XyzI for int32s?

I honestly think problem is a result of Microsoft's guidelines on "namespaces should match folder structure". Take a look at one of top answers's on StackOverflow for this:

I found the simplest and most productive route was to have a single namespace per project and all classes go into that namespace. ... It is important to organize source files into folders and in my opinion that's all folders should be used for. Requiring that these folders also map to namespaces is unnecessary, creates more work, and I found was actually harmful to organization because the added burden encourages disorganization.

So what I'm thinking of is everything for the core project for example would have the namespace MonoGame.Extended. Then the folders are just how the developers organize the code and is a detail hidden to the consumer of the library. This also makes it simple for the consumer to bring in one required namespace when using each project rather than bringing multiple namespaces in for each feature in a project.

e.g. to use bitmap fonts in the core package the consumer needs to do the following:

using MonoGame.Extended;
using MonoGame.Extended.BitmapFonts;

This requires documenation to bring in the namespace as it's not immediately evident. And I know how much flak there is for docuemnation already! So the opposite is actually easier for consumers with little documenation:

using MonoGame.Extended;

The only downside is it's not the convention, could be confusing the first time it's encountered, and possible lead to more disorganization if the folder names are not reasonable. In that case option 1 you mentioned would be better even if it requires a using statement for consumers.

craftworkgames commented 5 years ago

So what I'm thinking of is everything for the core project for example would have the namespace MonoGame.Extended. Then the folders are just how the developers organize the code and is a detail hidden to the consumer of the library.

@lithiumtoast you make some compelling arguments (or rather Weyland Yutani on stack overflow made most of them 😉).

It certainly feels like a good idea on the surface. It would allow us to reorganize the files in a more sensible way without having to worry so much about the namespace they live in.

It won't be without a bit of pain initially though. Unfortunately, deleting existing namespaces (which is what we'd have to do) is a breaking change. So for a little while at least, it'll probably cause a bit of confusion. Hopefully no more than simply moving things around though.

The main issue I really see with this is the tooling. Most of the tooling in Visual Studio, Resharper or whatever you're using defaults to having a namespace per folder. Before we go ahead with this it'd be worth investigating to see if we can configure the project file to follow these new rules.

In summary, I'm cautiously in favor of doing it. I think it's worth a try. We can always go back to the old way if it doesn't work out.

Re-visiting MonoGame I find it ungodly how there is just so much code in one directory. It makes it hard to reason about the modules of code, such as which classes or structs are interconnected or possibly interconnected, without opening the files and analyzing the code itself. MonoGame.Extended is showing similiar problems now too as the core package grows.

This I agree with. One thing is clear, spending some time organizing our files will be worth the effort.

Did I mention I'm thinking to add TriangleF and all the XyzD for doubles and XyzI for int32s?

No, you haven't mentioned that before. What's that all about?

lithiumtoast commented 5 years ago

The main issue I really see with this is the tooling. Most of the tooling in Visual Studio, Resharper or whatever you're using defaults to having a namespace per folder. Before we go ahead with this it'd be worth investigating to see if we can configure the project file to follow these new rules.

There are a couple options.

  1. With ReSharper you can right click the warning/error select ignore. I would not recommend as it is applies to your user settings of ReSharper.
screen shot 2019-02-16 at 2 42 04 pm screen shot 2019-02-16 at 2 44 23 pm

You can change it back by going into settings like so and click the curled arrow.

screen shot 2019-02-16 at 2 51 35 pm
  1. Apply a ReSharper comment to ignore the warning/error at every place it occurs (every file). Note it must be placed above the namespace.
screen shot 2019-02-16 at 2 57 11 pm
  1. For folders only. Right click the folder and open up the properties dialog and uncheck the namespace provider. ReSharper will then ignore namespaces for any code in that folder.
screen shot 2019-02-16 at 2 58 52 pm screen shot 2019-02-16 at 3 00 47 pm

Option 3 is probably best imo; it's the only thing that has to be done and all the files don't have to be modified.

EDIT: When you do option 3, a PROJECTNAME.csproj.DotSettings is created by ReSharper to store the settings. Thus the settings can be checked into source control if this file is allowed in the .gitignore file.

What's also great about option 3 is we can do it just for the changes we need right now without making breaking changes across the whole project. e.g. by adding a Math folder with namespace provider set to false.

lithiumtoast commented 5 years ago

Did I mention I'm thinking to add TriangleF and all the XyzD for doubles and XyzI for int32s?

No, you haven't mentioned that before. What's that all about?

I'm thinking of adding at least TriangleF for sure. The rest I have thought about for for symmetry, but people probably wouldn't use them the majority of the time so I don't think it's worth the trouble. Also hopefully C# gets something more advanced than generics in the future to solve this problem like templates in C++. Also the ability to define usable types from templates, like struct Point2f = Point2<float>.

stefanrbk commented 5 years ago

Also the ability to define usable types from templates, like struct Point2f = Point2<float> .

This does already exist, just on a per-file level.

using Point2f = MonoGame.Extended.Point2<float>;
toore commented 6 months ago

Late reply ;) I've created a OrientedRectangle (which is mentioned in the thread above) and it supports collision management and calculates penetration vector.

See the branch in my cloned repo https://github.com/toore/MonoGame.Extended/tree/feature-oriented-bounding-rectangle.

Should I create a PR?