Implementing a “grab” camera panning tool in a 3D

2019-07-10 04:58发布

In my scene I have terrain that I want to "grab" and then have the camera pan (with its height, view vector, field of view, etc. all remaining the same) as I move the cursor.

So the initial "grab" point will be the working point in world space, and I'd like that point to remain under the cursor as I drag.

My current solution is to take the previous and current screen points, unproject them, subtract one from the other, and translate my camera with that vector. This is close to what I want, but the cursor doesn't stay exactly over the initial scene position, which can be problematic if you start near the edge of the terrain.

// Calculate scene points
MthPoint3D current_scene_point =
   camera->screenToScene(current_point.x, current_point.y);
MthPoint3D previous_scene_point =
   camera->screenToScene(previous_point.x, previous_point.y);

// Make sure the cursor didn't go off the terrain
if (current_scene_point.x != MAX_FLOAT &&
    previous_scene_point.x != MAX_FLOAT)
{
   // Move the camera to match the distance
   // covered by the cursor in the scene
   camera->translate(
      MthVector3D(
         previous_scene_point.x - current_scene_point.x,
         previous_scene_point.y - current_scene_point.y,
         0.0));
}

Any ideas are appreciated.

标签: opengl 3d
1条回答
男人必须洒脱
2楼-- · 2019-07-10 05:14

With some more sleep :

  • Get the initial position of your intersected point, in world space and in model space ( relative to the model's origin)

i.e use screenToScene()

  • Create a ray that goes from the camera through the mouse position : {ray.start, ray.dir}

ray.start is camera.pos, ray.dir is (screenToScene() - camera.pos)

  • Solve NewPos = ray.start + x * ray.dir knowing that NewPos.y = initialpos_worldspace.y;

-> ray.start.y + x*ray.dir.y = initialpos_worldspace.y

-> x = ( initialpos_worldspace.y - ray.start.y)/rad.dir.y (beware of dividebyzeroexception)

-> reinject x in NewPos_worldspace = ray.start + x * ray.dir

  • substract initialpos_modelspace from that to "re-center" the model

The last bit seems suspect, though.

查看更多
登录 后发表回答