I am using below code to pan the viewport (action script 3 code using flare3d framework)

_mainCamera.x-= Input3D.mouseXSpeed;
_mainCamera.z+= Input3D.mouseYSpeed;

Where as Input3D.mouse[X|Y]Speed gives the displacement of the mouse on the X/Y axis starting from the position of the last frame.

This works perfect if my camera is not rotated. However, if I rotate the camera (x by 30, y by 60) and pan the camera then it goes wrong. Which is actually correctly panning according to the code. But this is not desired and I know I need to do some math to get the correct x/y which I am not aware of it.

Can some one help me achieving it?


I am getting an Idea but I am not sure how to do it :(

  1. Get the mouseX/Y deltas (xd,yd)
  2. Get the current camera coords (pos3d)
  3. Convert to screen coords (pos2d)
  4. Add deltas to screen coords (pos2d+ (xd,yd))
  5. Convert above coords to 3d coords
  • \$\begingroup\$ If you need help with my answer just say anything.... \$\endgroup\$ – jmacedo Oct 22 '12 at 17:06
  • \$\begingroup\$ I am very new to 3d, so if you can help me understand how your code achieves my requirement would be helpful. \$\endgroup\$ – Noob Game Developer Oct 23 '12 at 5:39
  • \$\begingroup\$ Your camera rotates around 1 or 2 axis? My answer only takes into account rotation around a single axis. I'll create an illustration of it. \$\endgroup\$ – jmacedo Oct 23 '12 at 19:54
  • \$\begingroup\$ The illustration explaining my reasoning is done, I updated my answer :) \$\endgroup\$ – jmacedo Oct 23 '12 at 21:25

I've faced this exact same issue a few days ago. I have a camera class which deals with camera logic. It has a method which receives the mouse deltas and according to it, changes the camera speed (because I have a smooth panning using speed instead of position), but for the position the reasoning is completly analogous. This code is in java but you can easily extract the math from it:

public void incSpeed(float deltaX, float deltaY){
    //{upx,upy} is the up vector of your camera
    float angDifUp = - (float) (Math.PI/2.0) + MyMath.vector2dAngle(new float[]{upx,upy});
    float angDelta = MyMath.vector2dAngle(new float[]{deltaX,deltaY});
    //Norm of the delta vector
    float normDelta = MyMath.distance2d(new float[]{deltaX,deltaY}, new float[]{0,0});
    float newDelta[] = new float[]{normDelta*FloatMath.cos(angDelta+angDifUp),normDelta*FloatMath.sin(angDelta+angDifUp)};

    vx += newDelta[0];
    vy += newDelta[1];

Up vector: http://www.charglerode.com/blog/wp-content/uploads/2009/07/cameranav2.jpg

This works by manipulating the panning vector according to the rotation of the camera.

You might have to provide the negative of deltaX and/or deltaY to the method for it to work correctly depending on how you calculate the deltas.

You may also need to take the minus sign out of the angDifUp variable.

If I were you I'd try the 8 combinations of (+/-|+/-|+/-) if it doest work right away.

If you want I might add extra explanations later.

Good luck.

Edit I made a sketchy illustration explaining the reasioning:

enter image description here

  • \$\begingroup\$ can you please help me translate this. I need to know what exactly vector2dangle does? \$\endgroup\$ – Noob Game Developer Oct 20 '12 at 11:29
  • \$\begingroup\$ In actionscript I think the atan2 function does exactly the same... try it. Anyway, if it doesnt work , use this: public static float vector2dAngle(float[] vector){ if(vector[0] != 0){ return (float) (vector[0] > 0 ? Math.atan(vector[1]/vector[0]) : Math.atan(vector[1]/vector[0]) - Math.PI);} else{ return (float) (vector[1] > 0 ? Math.PI/2 : -Math.PI/2);} } \$\endgroup\$ – jmacedo Oct 20 '12 at 12:21
  • \$\begingroup\$ @NoobGameDeveloper To know what the code above calculates see: people.sinclair.edu/nickreeder/eet155/PageArt/vector.gif \$\endgroup\$ – jmacedo Oct 20 '12 at 12:42

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.