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.