So after a long day of hacking my own subprime camera class, I went for openGL routines instead.
within minutes I had the behaviour I was after (zooming in on the mouse position)
I did it like this
GL.Viewport(0, 0, ClientRectangle.Width, ClientRectangle.Height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.Ortho(
centerX - ( width / 2.0 ),
centerX + ( width / 2.0 ),
centerY - ( height / 2.0 ),
centerY + ( height / 2.0 ),
-1,
1
);
GL.MatrixMode(MatrixMode.Modelview);
the actual zooming in on te center is done in this fuction
void HandleWheelChanged (object sender, OpenTK.Input.MouseWheelEventArgs e)
{
var my = 600 - e.Y;
var mx = e.X;
double x = (mx / (double)(WIDTH)) - 0.5;
double y = (my / (double)(HEIGHT)) - 0.5;
double preX = (x * width);
double preY = (y * height);
double zoomFactor = 1.5;
if (e.Delta > 0) {
width/=zoomFactor;
height/=zoomFactor;
}
if( e.Delta < 0 )
{
// zoom out
width *= zoomFactor;
height *= zoomFactor;
}
double postX = ( x * width );
double postY = ( y * height );
centerX += ( preX - postX );
centerY += ( preY - postY );
scaleX = 1.0/(width/WIDTH);
scaleY = 1.0/(height/HEIGHT);
Console.WriteLine("width:{0}, scaleX:{1}",width,scaleX);
OnResize(null);
}
all of this is fine and dandy, bu now my mousepicking routines are not working anymore.
I had thought I just needed to plug in the centreX, centreY and scaleX, scaleY to get it working.
but the output is changing radically.
public float[] ScreenToLocal (float x, float y, Camera cam)
{
ms.Vector2 point = new ms.Vector2(x, y);
var cx = (float)cam.CenterX;
var cy = (float)cam.CenterY;
var sx = (float)cam.ScaleX;
var sy = (float)cam.ScaleY;
ms.Matrix viewMatrix = ms.Matrix.CreateTranslation(-source.Width/2,-source.Height/2, 0f ) *
ms.Matrix.CreateRotationZ((float)GM.DegreeToRadian(source.Rotation)) *
ms.Matrix.CreateScale(sx,sy, 1f) *
ms.Matrix.CreateTranslation(source.Position.X+source.Width/2, source.Position.Y+source.Height/2, 0f );
viewMatrix = ms.Matrix.Invert(viewMatrix);
ms.Vector2 rotatedPoint = ms.Vector2.Transform(point, viewMatrix);
return new float[]{rotatedPoint.X, rotatedPoint.Y};
}
as you can see I hacked a little in the CreateTranslation call; but I don't really get it, I've tried swapping around all vaiables and am pulling out hairs here.
Am I missing something or just pain silly?