XNA 2d camera with arbitrary zoom center

I have a working 2D camera in XNA with these guts:

ms = Mouse.GetState(); msv = new Vector2(ms.X, ms.Y); //screenspace mouse vecor pos = new Vector2(0, 0); //camera center of view zoom_center = cursor; //I would like to be able to define the zoom center in world coords offset = new Vector2(scrnwidth / 2, scrnheight / 2); transmatrix = Matrix.CreateTranslation(-pos.X, -pos.Y, 0) * Matrix.CreateScale(scale, scale, 1) * Matrix.CreateTranslation(offset.X, offset.Y, 0); inverse = Matrix.Invert(transmatrix); cursor = Vector2.Transform(msv, inverse); //the mouse position in world coords 

I can move the position of the camera and change the zoom level (with a different code, which I did not insert here for brevity). The camera always scales around the center of the screen, but I would like to be able to scale any arbitrary zoom point (cursor in this case), for example, indie game dyson http://www.youtube.com/watch?v=YiwjjCMqnpg&feature=player_detailpage#t= 144s

I tried all the combinations that make sense to me, but I'm completely stuck.

+4
source share
2 answers

I did this, this is the code and explanations:

Get mouse outlines in camera space:

  msx = Mouse.X - Viewport.Width/2; msy = Mouse.Y - Viewport.Height/2; 

Get the distance from the camera to the mouse in the camera space

  var width = CameraTranslation.X - msX; var height = CameraTranslaton.Y + msY; 

Get the offset created by the new zoom, and then subtract it to the camera position

  CameraTranslation.X -= width * (1-newZoom/_zoom); CameraTranslation.Y -= height * (1-newZoom/_zoom); _zoom = newZoom; 
+4
source

In fact, you will not approach the cursor. You will scale the point defined on the line between the previous center of zoom and the cursor. As you zoom in further, this point approaches the cursor position. In addition, it should move to the cursor faster if you zoom in. You zoom_center should be defined as something similar (Note: I introduced new variables and added a line where you reassign pos to zoom_center).

 zoom_center = pos = cursor + (scale_prior_to_zoom/scale) * (pos - cursor); 

Hope this works as I was only trying on paper, so you might need to change this a bit ... but that should make you at least point in the right direction. Here's the math support I did only with size X.

cursor = (1,1)

pos = (5.5)

Zooming The position should be closer to the cursor.

scale = 2 scale_prior_to_zoom = 1

posX = 1 + (1/2) (5 - 1)

posX = 1 + 0.5 * 4

posX = 1 + 2

posX = 3

Scaling The position should be further from the cursor.

scale = 1 scale_prior_to_zoom = 2

posX = 1 + (2/1) (5 - 1)

posX = 1 + 2 * 4

posX = 1 + 8

posX = 9

+2
source

Source: https://habr.com/ru/post/1397279/


All Articles