Results 1 to 3 of 3

Thread: Moving a viewport by dragging the mouse.

  1. #1

    Moving a viewport by dragging the mouse.

    Hi everyone

    Glad to see PGD becoming an active community again. To stir things up more, i have an interesting question for you.

    I'm working on an UV-mapping tool and i want to be able to move the viewport by dragging the right mouse. I mean that when start to drag in the viewport, the coordinate system will stick to my mouse so i can move around and look at different area's.

    This is my attempt:

    [PASCAL]
    //DragMoving indicates whether we are moving by dragging the mouse
    //UVPos is the UV-position of the viewport (UV coordinate at the center of the view)
    //StartVec is the position in UV-space were we started to move
    //StartPos is the UVPos that was saved when we started dragmoving
    //MouseVec is the current UV-coordinate at which the mouse points.

    procedure TMainForm.ViewUVMouseDown(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
    begin
    if Button = mbRight then
    begin
    DragMoving := True;

    GL.UnProjectUV(X, Y, StartVec.x, StartVec.y);
    StartPos.x := UVPos.u;
    StartPos.y := UVPos.v;
    end;
    end;

    procedure TMainForm.ViewUVMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    begin
    if DragMoving then
    begin
    //Unproject mouse coordinates
    GL.UnProjectUV(X, Y, MouseVec.x, MouseVec.y);

    //Update position of Viewport
    UVPos.u := StartPos.x + (StartVec.x - MouseVec.x);
    UVPos.v := StartPos.y + (StartVec.y - MouseVec.y);
    end;
    end;

    procedure TMainForm.ViewUVMouvseUp(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
    begin
    if Button = mbRight then DragMoving := False;
    end;

    procedure TGLRenderer.UnProjectUV(X, Y: Integer; out U, V: Single);
    var
    viewport: TGLVectori4;
    modelview: TGLMatrixd4;
    projection: TGLMatrixd4;
    dU, dV, dW: Double;
    begin
    //Set UV matrices
    ViewUV(fUVPosition.u, fUVPosition.v, fUVViewSize);

    //Retrieve matrices
    glGetDoublev( GL_MODELVIEW_MATRIX, @modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, @projection );
    glGetIntegerv( GL_VIEWPORT, @viewport );

    // In Delphi A Y Value Of 0 Returns An Unknown Value
    // I Discovered This While I Was Testing A Crosshair
    if( Y = 0 )then Y := 1;

    gluUnProject( X, viewport[3]-Y, 0,
    modelview, projection, viewport,
    @dU, @dV, @dW);

    //Convert from Double to Single
    U := dU;
    V := dV;
    end;
    [/PASCAL]

    It works, but it becomes jerky very quickly. I figure that that is caused by some "feedback" effect. MouseVec depends on the position of the viewport (UVPos), but MouseVec also AFFECTS the position of the viewport. It's like a circle.

    I'm looking for a better sollution, but i can't think of one. Can someone help me?

    Thanks in advance.

    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  2. #2

    Re: Moving a viewport by dragging the mouse.

    Hi there. I'm not sure if this is the same thing, but i use a similar method for my apps in GLScene (admittedly a LOT of the hard work is done for me ) I only store the screen co-ords though:

    Psuedo
    Code:
    var
     oldx,oldy : integer; // previous mouse position
    
    onMouseDown:
    begin
     oldx =mousex; 
     oldy =mousey;
    end;
    
    onMouseMove(X,Y: integer / mouse position passed to procedure):
    var
     owv,wv: TVector (array[0..3] of single); // old and current world position
    begin
     owv = ScreenVectorIntersectWithPlaneXZ(oldx,oldy)
     wv =ScreenVectorIntersectWithPlaneXZ(X,Y) 
     camera position = camera position + (vectorsubtract(owv,wv))
     oldx =x; oldy = y; <- important otherwise you get acceleration (which is what you might be getting)
    end;
    Or have i got completely the wrong end of the stick?(it wouldn't be the first time!)
    Windows Vista x64 Ultimate<br />AMD Athlon x64 4000+<br />Codegear Delphi 2009, Delphi 2007, Borland Delphi 7

  3. #3

    Re: Moving a viewport by dragging the mouse.

    Thanks for your reply. It works now

    Here's the source:

    [pascal]
    //StartMousePos is the starting point of the mouse in screen coordinates
    //MousePos is the current position of the mouse in screen coordinates
    //UVPos is the current UV-position of the viewport center
    //StartUVPos is the initial UV-position of the viewport center (when we started dragging).

    procedure TMainForm.ViewUVMouseDown(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
    begin
    if Button = mbRight then
    begin
    DragMoving := True;
    StartMousePos.X := X;
    StartMousePos.Y := Y;
    StartUVPos.u := UVPos.u;
    StartUVPos.v := UVPos.v;
    end;
    end;

    procedure TMainForm.ViewUVMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    var
    uFactor, vFactor: Single;
    begin
    if DragMoving then
    begin
    MousePos.X := X;
    MousePos.Y := Y;

    //Scales displacement-vector from screen to UV-coordinates (Flip Y-axis)
    uFactor := UVSize/ViewUV.Width;
    vFactor := -(UVSize/ViewUV.Height);

    //Transform displacement vector and combine it with the initial viewport position
    UVPos.u := StartUVPos.u - (MousePos.x - StartMousePos.x)*uFactor;
    UVPos.v := StartUVPos.v - (MousePos.y - StartMousePos.y)*vFactor;
    end;
    end;

    procedure TMainForm.ViewUVMouvseUp(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
    begin
    if Button = mbRight then
    begin
    DragMoving := False;
    MousePos.X := 0;
    MousePos.Y := 0;
    StartMousePos.X := 0;
    StartMousePos.Y := 0;
    end;
    end;
    [/pascal]

    Instead of using gluUnProject, i figured that it was easier to just transform by hand. If you want to rotate your view, this can be tedious though, but i don't need this. I got rid of the "feedback" effect now.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •