craftworkgames / MonoGame.Extended

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

[Core] Duplicate `struct`s for things already available in `Microsoft.Xna.Framework` #538

Closed fdrobidoux closed 4 months ago

fdrobidoux commented 6 years ago

For example : Why have a Size and a Size2 if they solve the same purpose? Why have a Point2 if Vector2 is much the same?

It's kinda weird to have different structs to do the exact same thing as something that exists already in the API, but with different names. I haven't checked yet, but I'm scared of seeing the dependencies those objects have.

Hopefully, this will be adressed with 2.0.

stefanrbk commented 6 years ago

This was briefly gone over here

craftworkgames commented 6 years ago

Honestly, I'm still on the fence about this. I'll certainly consider it for 2.0.

lithiumtoast commented 4 years ago

Similar to #650

Point2 will be removed in favour of Vector2. I made previous comments about why Point2 was created here. With System.Numerics, the responsibility of Vector2 is taken over by the .NET team.

lithiumtoast commented 3 years ago

Actually I think keeping Point2 would be good with the new direction of v4. The issue of why Point2 exists when Vector2 exists could be better explained via documentation.

lithiumtoast commented 3 years ago

It's kinda weird to have different structs to do the exact same thing as something that exists already in the API, but with different names. I haven't checked yet, but I'm scared of seeing the dependencies those objects have.

This is the exact problem being addressed with v4 by forking FNA. Vector2 however will be picked up from System.Numerics while other structs will be removed from the Microsoft.Xna.Framework namespace such as Rectangle.

stefanrbk commented 3 years ago

I have actually been looking into the .NET 5 code behind the System.Numerics namespace. There are loads of JIT optimizations and intrinsics running behind the scenes which greatly improve performance. I did a few benchmarks about a month ago and a duplicate of any of the System.Numerics structs, identical down to the IL code, runs about 75-50% slower than the legitimate version. I know I haven't worked actively on the project in a few years, but hopefully this helps! 😁

lithiumtoast commented 3 years ago

@stefanrbk That's one major driving force for sure. I'm creating a game (from a fork of FNA) and re-doing some of the code in Extended. I think I would rather drop Point2 after looking at all the code I would have to maintain. I think that the problem is just an educational problem. I could tackle the "Point vs Vector" problem with proper documentation.

To recap: From a mathematical perspective, a "point" is not a "vector," but they are similar!

A mathematical vector describes a length and a direction. An arrow can usefully represent a vector. Two vectors are equal if they have the same length and direction, even if we think of them as being located in different places. Vectors are often used to store a displacement or offset in space. Points, on the other hand, are locations in space. The difference is that points are anchored to some origin while vectors don't have any meaning of an origin. Game developers commonly think of a vector as a point by saying that zero is the origin, but vectors could be starting at any origin, not just zero. For the mathematically curious, see https://math.stackexchange.com/questions/645672/what-is-the-difference-between-a-point-and-a-vector and http://immersivemath.com/ila/ch02_vectors/ch02.html.

The pragmatic approach here is that if you come across a vector that is masking as a point, you should think of it as a displacement from zero, the result of which is a location. However, it would be best to take care that a vector in any other context does not have to start from the origin of zero.

lithiumtoast commented 3 years ago

So the solution here is that System.Numerics with Vector2 will be used instead of Point2 or Size or Size2 or anything like that. A Vector2 is a displacement which could encode any of Point2, Size or Size2, but the context is very important; that is where proper documentation will be required.

stefanrbk commented 3 years ago

Something for that education piece there (although this does contain a bit of speculation/assumption from me, but it makes more sense to me): Vector2 and all the "Vector*" data structures in System.Numberics are referring to a "vector" in terms of computer science, not mathematics. Either it is referring to C++ where a Vector is similar to a List<T> in C#, or it refers to the act of doing 1 CPU operation on multiple pieces of data at the same time called either "SIMD" or "vector operations".

I'm thinking any kind of explanation when it comes to documentation could be as simple as "There are multiple conflicting definition of vectors in computer science and programming. Here it means a specified number of float values passed around together."

lithiumtoast commented 3 years ago

A vector does not have to be Euclidean or spatial. The components of a vector could be any tuple such that the components respect addition and multiplication operations so that they form a vector space. The std::vector in C++ is just a dynamic array with amortized constant time; the equivalent of List<T> in C#. The name vector was IMO a poor choice for a dynamic array.

stefanrbk commented 3 years ago

I completely agree. I have been working on SIMD with LOADS of VectorXXX<T> use, and every time I try searching for "vectors" I get std::vector more often than not =/

AristurtleDev commented 4 months ago

Reading through the history of this issue, the topic kinda diverged into System.Numerics as such things tend to do.

At this time, I do not believe that updating the code base to support the System.Numerics types is feasible. In order to do that, significant changes in the code base would need to be made to differentiate between System.Numerics.Vector* types and Microsoft.Xna.Framework.Vector* types due to type collisions between the two namespaces.

The above could be solved by with using aliases, however this still means that System.Numerics is only used internally inside MonoGame.Extended and any types passed back to consumers would need to be cast back to the Microsoft.Xna.Framework types.

There has already been some work done within MonoGame for these types with methods such as Vector2.ToNumerics. The current discourse from the MonoGame maintainers seems to be that an overhaul to switch to System.Numerics will not happen until the 5.0 release. See this issue thread to follow that conversation: https://github.com/MonoGame/MonoGame/issues/7204

I believe that until such time that base MonoGame itself switches to using System.Numerics, the topic of doing this should be put on the backburner in favor of being able to continue to maintain this project without issue.

AristurtleDev commented 4 months ago

To address the original reason this issue was opened, I agree with the submitted.
Point2 doesn't make sense to have when it's the same thing as a Vector2. This just creates noise for which type the user should use.

We can debate semantics about Point vs Vector in mathematics or computer science, but in the end, this does nothing to further helping the user base and having so many different types (Point2, Point3, Size2, Size3) just creates more confusion for the end user than needed.

I'm in favor of removing these types. However I would like to keep the Size type. Even though internally it functions very similar to what a Point offers (and even Microsoft.Xna.Framework.Rectangle.Bounds.Size is a Point value), I believe there is a valid use case for have a type specially called Size to use in various scenarios.

AristurtleDev commented 4 months ago

Size3, Point3, and Point2 have been removed from the library. These types are equivalent to existing types within MonoGame already (i.e. Vector3 and Vector2).

Size is kept to have a struct that represents an actual size instead of just using Point. Size2 has been renamed to SizeF to keep naming consistency with other types such as RectangleF