Zoomen in GLScene

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Zoomen in GLScene

Beitrag von fliegermichl »

Hallo,
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?

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Zoomen in GLScene

Beitrag von fliegermichl »

Hat sich erledigt.

Nach dem Anpassen von GLCamera1.SceneScale ist der alte Zentrumspunkt natürlich auch nicht mehr gültig.
Ich ermittle jetzt erneut, welcher Punkt sich unter der Maus befindet, bilde die Differenz zur Mitte und verschiebe um diesen Betrag.

Jetzt zoomt die Scene einwandfrei an dem Punkt an dem die Maus ist.

Antworten