rnd_nr_gen
rnd_nr_gen

Reputation: 2281

Mapping from 2D projection back to 3D point cloud

I have a 3D model consisting of point vertices (XYZ) and eventually triangular faces. Using OpenGL or camera-view-matrix-projection I can project the 3D model to a 2D plane, i.e. a view window or an image with m*n resolution.

The question is how can I determine the correspondence between a pixel from the 2D projection plan and its corresponding vertex (or face) from the original 3D model.

Namely,
What is the closest vertices in 3D model for a given pixel from 2D projection?
It sounds like picking in openGL or raytracing problem. Is there however any easy solution?

With the idea of ray tracing it is actually about finding the first vertex/face intersected with the ray from a view point. Can someone show me some tutorial or examples? I would like to find an algorithm independent from using OpenGL.

Upvotes: 5

Views: 2420

Answers (3)

kvark
kvark

Reputation: 5361

In addition to Ben Voigt's answer:

  1. If you do a separate pass over pickable objects, then you can set the viewport to contain only a single pixel that you will read.

  2. You can also encode triangle ID by using geometry shader (gl_PrimitiveID).

Upvotes: 1

Phrogz
Phrogz

Reputation: 303411

My (possibly-naive) thought would be to create an array of the vertices and then sort them by their distance (or distance-squared, for speed) once projected to your screen point. The first item in the list will be closest. It will be O(n) for n vertices, but no worse.

Edit: Better for speed and memory: simply loop through all vertices and keep track of the vertex whose projection is closest (distance squared) to your viewport pixel. This assumes that you are able to perform the projection yourself, without relying on OpenGL.

For example, in pseudo-code:

function findPointFromViewPortXY( pointOnViewport )
  closestPoint = false
  bestDistance = false
  for (each point in points)
    projectedXY     = projectOntoViewport(point)
    distanceSquared = distanceBetween(projectedXY, pointOnViewport)
    if bestDistance==false or distanceSquared<bestDistance
      closestPoint = point
      bestDistance = distanceSquared
  return closestPoint

Upvotes: 1

Ben Voigt
Ben Voigt

Reputation: 283763

Hit testing in OpenGL usually is done without raytracing. Instead, as each primitive is rendered, a plane in the output is used to store the unique ID of the primitive. Hit testing is then as simple as reading the ID plane at the cursor location.

Upvotes: 2

Related Questions