craftworkgames / MonoGame.Extended

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

Sugestion: Support Camera2D for different coordinate system. #160

Closed maties7 closed 8 years ago

maties7 commented 8 years ago

I have a suggestion to add method to the camera with will support coordinate system not based on pixels (such as Farseer Physics). Currently, is possible draw scene on right position by using argument parallaxFactor in GetViewMatrix, but this only work until you use zoom or rotation. The problem is very easy to solve, because you need multiply also origin of camera.

craftworkgames commented 8 years ago

Sounds like an interesting idea. How would it work?

maties7 commented 8 years ago

In samples from FarseerPhysics you can find an example Camera2d that supports the normal matrix view and SimView matrix. ([Camera2D](https://farseerphysics.codeplex.com/SourceControl/latest#Samples/Samples MonoGame/ScreenSystem/Camera2D.cs))

Projection and view matrices are needed to correct display of objects placed in a different coordinate system. Firstly, a good option was the possibility to get the default projection matrix. In my project I have to create by yourself and looks like this:

Matrix projection = Matrix.CreateOrthographicOffCenter (0f, 
ConvertUnits.ToSimUnits(graphics.GraphicsDevice.Viewport.Width)
ConvertUnits.ToSimUnits(graphics.GraphicsDevice.Viewport.Height), 
0f, 0f, 1f);

Where class ConvertUnits is from ConvertUnits

The next thing is get the matrix view. The first thing I tried pass ConvertUnits.ToSimUnits(Vector2.One) to GetViewMatrix(Vector2 parallaxFactor). At first, the effect was satisfactory but when I tried zoom or rotate view, then elements in debugView of FarseerPhysics start moving in unexpected way. The reason is not scaled origin. In my code I wrote a method that allows me the normal behaviour of the camera during zoom and rotation.

public static Matrix GetViewSimMatrix(this Camera2D camera, Vector2 factor)
{
    Vector2 tmpOrigin = camera.Origin;
    camera.Origin * = factor;
    Matrix viewMatrix = camera.GetViewMatrix (factor);
    camera.Origin = tmpOrigin;
    return viewMatrix;
}

I think in the library should appear method similar to GetViewMatrix(Vector2 parallaxFactor), but with the difference that not only the position will be scaled but also the center of the camera.

craftworkgames commented 8 years ago

yeah, the camera in Farseer is quite good and makes a lot of sense. We just have to figure out how to incorporate this into MonoGame.Extended without breaking everything.

I also wonder if support for a different coordinate system makes sense in other parts of the library. I know working in pixels can be pain sometimes.

Are you interesting in working on this? If so I can create a new branch and we'll keep the changes there until we are confident it makes sense.

maties7 commented 8 years ago

I think is not so difficult to implement new functionality without breaking anything.

If other parts of the library isn't used different coordinate system that these changes are useless. But for external library is different story.

I think the new branch is a pretty good idea. It will be easier to discuss whether the changes make sense. I also have to write some demo for testing.

craftworkgames commented 8 years ago

Okay I've created a branch called camera-coordinates.

craftworkgames commented 8 years ago

We'll open this again if interest arises.