Ich habe eine Scene mit der Kamera im Style csOrthogonal.
Wenn man per GLCamera.SceneScale zoomt, passiert das in der Mitte der aktuellen Ansicht.
Ich möchte erreichen, daß der Punkt unter der Maus das Zentrum der Zoomerei ist.
Zu dem Zweck ermittle ich vor dem Zoomen den Punkt unter der Maus, verschiebe den in die Mitte der Ansicht, zoomen und dann den Punkt wieder an die gleiche Stelle zurück.
Das klappt auch fast aber eben nur fast.
Hier der Code von TGLSceneViewer(sv).MouseWheel.
Code: Alles auswählen
procedure TForm1.svMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var sc : single;
mp, cp, diff : TAffineVector;
d : TAffineVector;
dx, dy : integer;
begin
mp := sv.Buffer.OrthoScreenToWorld(MousePos.x, MousePos.y); // Punkt unter der Maus ermitteln
cp := sv.Buffer.OrthoScreenToWorld(sv.ClientWidth shr 1, sv.ClientHeight shr 1); // aktuelles Zentrum ermitteln
diff := VectorSubtract(mp, cp); // Differenz berechnen
GLCamera1.MoveTargetInEyeSpace(0, diff[0], -diff[1]); // Punkt unter der Maus in das Zentrum verschieben
if GLCamera1.CameraStyle = csPerspective then
GLCamera1.AdjustDistanceToTarget(Power(1.1, -WheelDelta / 120))
else if GLCamera1.CameraStyle = csOrthogonal then
begin
sc := GLCamera1.SceneScale;
if WheelDelta > 0 then
sc := sc * 1.1
else
sc := sc * 0.9;
GLCamera1.SceneScale := sc;
end;
// Herausfinden, wo der Punkt, der vorher unter der Maus war jetzt ist
d := sv.Buffer.WorldToScreen(mp);
dx := Round(d[0]);
dy := Round(sv.clientheight-d[1]);
mp := sv.buffer.OrthoScreenToWorld(dx, dy);
diff := VectorSubtract(cp, mp);
GLCamera1.MoveTargetInEyeSpace(0, diff[0], diff[1]);
end;
Kann mir jemand sagen wo der Fehler ist?