12

I have designed a C++ class that abstracts the user from trackball rotation, zooming and panning. I have got the rotation (using trackball) and zooming working as expected. However, panning does not behave as expected. When I pick a point and drag, I expect that on finishing drag, the picked point continues to be under the mouse. My understanding of panning in perspective projection is as follows. The target and the camera position, both will be affected by a pan operation. The camera target and the camera position (eye) should be translated proportional to the drag. The proportionality (may not be constant) should be based on z depth.

Panning is straight forward in orthographic projection but poses a problem in perspective. It will be useful if one can explain the math and the implementation detail for OpenGL.

Ram
  • 3,045
  • 3
  • 27
  • 42
  • Are you changing cam or the whole world to get the results? – huseyin tugrul buyukisik Aug 23 '12 at 18:20
  • I have implemented both. But I prefer to transform the world as it does not involve computing the inverse of model-view matrix. However, I am fine if I have a solution in either approach. – Ram Aug 23 '12 at 18:22
  • "However, panning does not behave as expected. When I pick a point and drag, I expect that on finishing drag, the picked point continues to be under the mouse". Is this like your mouse button latched and didnt let go? – huseyin tugrul buyukisik Aug 23 '12 at 18:28
  • Yes. When I press lButtonDown, I have picked an imaginary point under the mouse and while I continue to keep the lButtonPressed, I can move the mouse in order to pan the scene. A similar example in 2D is a pdf document viewer where the user grabs a point on the page and moves the view area. – Ram Aug 23 '12 at 18:32
  • When the lButtonUp happens, a flag that represents dragging is unset. I think I misunderstood what you asked in your last comment. The event mechanism is not a problem. The implementation of panning in OpenGL is the problem. – Ram Aug 23 '12 at 18:36
  • Are you attaching a "face to" vector when you get lButtonDown and make the "face to" vector equal to the focus point when you lButtonUp? Anyway, here is spherical coordinates that may interest you: http://www.arcsynthesis.org/gltut/Positioning/Tutorial%2007.html – huseyin tugrul buyukisik Aug 23 '12 at 18:42
  • And this question can me more useful : http://gamedev.stackexchange.com/questions/31285/panning-with-the-opengl-camera-view-matrix – huseyin tugrul buyukisik Aug 23 '12 at 18:42
  • 2
    I bet you can get real good answers and reputation from http://gamedev.stackexchange.com – huseyin tugrul buyukisik Aug 23 '12 at 18:44
  • tuğrul büyükışık, thanks for the links and your time. I have them open and will go through them. I am not sure what do you mean by "face to" vector. – Ram Aug 23 '12 at 18:46
  • "look to" vector or "look at" vector – huseyin tugrul buyukisik Aug 23 '12 at 18:52
  • Yes, in the current implementation, camera position and the target and being modified based on x and y displacement during drag and a proportionality using heuristics. The gluLookAt function takes the camera pos (eye), target and the up vector. – Ram Aug 23 '12 at 18:56
  • Hi Ram, have you made it? Because I have your same problem and I would like to ask you a couple of things.. – elect Mar 25 '14 at 08:15
  • Yes, I got it working. – Ram Apr 08 '14 at 09:12

2 Answers2

10

I don't know about the OpenGL specifics, but if I understand your question correctly I can help out with the mathematics:

I assume you have already selected the object, by clicking the object and thus "sending" a ray through your scene that hits your object in the anchorpoint p.

To understand the following:

Panning with perspective projection

Now you drag your mouse along vector t. Using the intercept theorem you can easily calculate the vector s by which p has to be translated to "keep it under the cursor":

|p| / |q| = |s| / |t|

|s| = ( |p| / |q| ) * |t|

s is parallel to t, so it is t normalized multiplicated by |s|:

s = t / |t| * |s|

s = t / |t| * ( |p| / |q| ) * |t|

s = t * ( |p| / |q| )

If you are panning, you are doing the exact same thing, just that you are not shifting p by s, but you have to translate your whole scene by -s.

flix
  • 609
  • 4
  • 9
  • "I assume you have already selected the object, by clicking the object and thus "sending" a ray through your scene that hits your object in the anchorpoint p." Not really. Panning anchor point may or may not lie on the object in the scene. However, I can construct a plane that passes through the target point and is normal to the view direction. I have not absorbed your math yet but your figure tells me it is not hard to calculate the displacement. Thanks for that. I will give it a go and see if it resolves my problem. – Ram Aug 23 '12 at 19:44
  • 1
    @Ram: For panning in perspective mode to work you need some anchor point. Think about it: If there's nothing under the mouse pointer, what is there to be kept under it? A robust implementation would graceful fall back to just moving the camera by a certain factor. – datenwolf Aug 23 '12 at 22:15
  • 1
    Well, right, it doesn't really matter how you got your point in the scene. I just wanted to point out, that you actually select a point belonging to an object as your "anchor point". I don't know how to write neat formulas on stackoverflow, but here's a little explanation: every letter stands for a vector as seen in the image, |p| is the length of vector p. In the first two lines I just used the intercept theorem as seen in the image, then rearranged the term to get the length of s. The three lines below show how you calculate the actual s from it's length |s| and it's direction given by t. – flix Aug 23 '12 at 22:25
0

It is impossible to have the finishing point under your mouse. Panning in perspective mode can be done in two ways. One is translating camera and the other is rotating camera. Translating camera will result in object rotation for user view. Rotation camera for panning has two constraints. one is not to change camera position and the other is to stop rotation with respect to camera direction. i.e., the axis of rotation should be parallel to the plane formed by camera right and up vectors.