4
\$\begingroup\$

I am trying to implement camera pan like the one in Maya. I've got it almost working.

The problem is that the mouse cursor is moving faster than the 3d mesh (in fact I am moving the camera but I said mesh, because it is more intuitive), while in Maya the distance between the mouse position and the mesh stays always the same.

This is what my code looks like :

glm::vec3 dist = cameraPos-modelPos;
float len=glm::length(dist);

float clipX = startX*2.0 / width - 1.0;
float clipY = 1.0 - startY*2.0 / height;

float clipEndX = lastX*2.0 / width - 1.0;
float clipEndY = 1.0 - lastY*2.0 / height;

// convert begin and end mouse positions into world space
glm::mat4 inverseMVP = glm::inverse(projection*view*modelMatrix);
glm::vec4 outVector = inverseMVP*glm::vec4(clipX, clipY, 0.0, 1.0);
glm::vec3 worldPos(outVector.x/outVector.w, outVector.y/outVector.w, outVector.z/outVector.w);

glm::vec4 outEndVec = inverseMVP*glm::vec4(clipEndX, clipEndY, 0.0, 1.0);
glm::vec3 worldPos2(outEndVec.x/outEndVec.w, outEndVec.y/outEndVec.w, outEndVec.z/outEndVec.w);

glm::vec3 dir = worldPos2 - worldPos;

glm::vec3 offset=glm::length(dir)*glm::normalize(dir)*angleFovRatio*len/2.f;
cameraPos-=offset;
cameraTarget-=offset;

Where angleFovRatio = std::tan(cameraFov*0.5f) I am using glm::lookAt(cameraPos, cameraTarget, cameraUp); for my view matrix

I will add picture of what my problem is:

enter image description here

As you can see, when I drag to the right, the red dots are my begin and end mouse positions. But the teapot is on the blue dot, which is not what I want. It must be centered on the second red dot (mouse end position, just like in maya).

\$\endgroup\$
  • \$\begingroup\$ Please describe the problem in more detail. Right now it is hard to tell what you get and what is wrong with that. \$\endgroup\$ – Kromster says support Monica Aug 7 '14 at 10:57
  • \$\begingroup\$ I've added more description \$\endgroup\$ – Geto Aug 7 '14 at 11:10
2
\$\begingroup\$

This is a general explanation answer, you'll have to check with the code yourself.

Perspective projection looks like this from above:

enter image description here

Near clipping plane is what you see on your screen. Now see that the farther you get from it, the more you need to move the object to have it in the same position on the screen.

For example take Blue point, it got moved from the middle to the right by 10m. If you move Red point by the same 10m you get it way to the right (hollow red point). To have Red point in the same place on the screen you need to move it by only 8m. Same applies to the Green point - to preserve it relative position on the screen it needs to be moved ~12m, otherwise it will appear to be moved too close relative to Blue point.

Another look at the situation is when you move the Camera 10m to the left. Imagine original setup with points being in the center of the Camera (hollow Red, Blue, hollow Green). When you move camera 10m to the left, points remain in place, but their projection to the screen changes - Green remains closer to center, Blue - farther and Red in the middle.

So it seems that when you move your cursor 100px you get the required distance from Blue points plane (10m), but your teapot object is in Green points plane, so it is moved the same 10m and it makes it look as moved too little on the screen (just 80px).

TL;DR: Calculate pan distance for the selected objects distance from camera.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.