2

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.

Nick McCowin
  • 449
  • 6
  • 12
  • Are you trying to "grab" an actual 3D point on your terrain, or can you live with grabbing the 2D point where Z=0? – genpfault Jun 02 '11 at 21:17
  • Well the idea is that the cursor will remain over the initial 3D point on the terrain, so that's what I'm trying to "grab". For instance, if you're looking at a scene with mountains in the distance, and you "grab" one of the mountain's peaks, as you drag (or pull) the cursor down, the mountain will come towards you while the cursor remains on the peak the entire time. – Nick McCowin Jun 02 '11 at 21:39
  • It's too late to think of a decent solution, but what you're trying to do is solving the system : { peak € ray from camera to mouse ; mountain.position.y = 0 }, right ? – Calvin1602 Jun 02 '11 at 22:23

1 Answers1

1

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.

Calvin1602
  • 9,413
  • 2
  • 44
  • 55