1
$\begingroup$

How can I get the distance between specific points in the 3D View and the virtual camera of my viewport?

Using the distance, I could select the closest or furthest (farthest) vertex/object from my perspective view.


Answering my own question, although I still don't know the difference between perspective_matrix, window_matrix and view_matrix. I also would prefer more explanation on why we don't need to use the inverted matrix.)
This question came up while creating this answer.

$\endgroup$
2
$\begingroup$

demo
Snapping an empty to the closest vertex of a cube. "Closest" meaning closest to the viewer.

First, loop through the areas or obtain a SpaceView3D by other means. The type of this area returns VIEW_3D. It's first space will be a VIEW_3D space. This space has a region_3d property, which has a perspective_matrix property.

The perspective_matrix appears to be the perspective view transform matrix. Mutliple a 3D Vector by the matrix, to get its position relativ to the camera.

Here is a working sample.

import bpy

# function returning the closest vertex of 
# param 'ob' is an object in the scene with vertices
def get_closest_vertex_position(scene, ob):
    # get an area of type VIEW_3D
    areas = [a for a in bpy.context.screen.areas if a.type == 'VIEW_3D']
    if not len(areas):
        return

    region3d = areas[0].spaces[0].region_3d

    # get the view matrix
    view_mat_inv = region3d.view_matrix

    if region3d.is_perspective:
        vertices = [[v, (view_mat_inv*v.co).length] for v in ob.data.vertices]
    else:
        vertices = [[v, -(view_mat_inv*v.co).z] for v in ob.data.vertices]

    # use a lamda expression to get closest vertex
    return min(vertices, key = lambda x: x[1])[0].co
$\endgroup$
  • 1
    $\begingroup$ Cool. Suggest doing this via a modal operator, a timer, or in a draw callback on the 3dview space rather than with a scene_update_pre . (depsgraph_update_pre on 2.8) handler. If for instance have two windows open with different scenes will confuse the result above. $\endgroup$ – batFINGER Jul 15 at 12:31
  • $\begingroup$ @bat Yes, definitely. This was merely a side product of this answer. I used the modal operator there. I'll just remove the last line, so future readers won't get tempted.^^ $\endgroup$ – Leander Jul 15 at 12:45
  • $\begingroup$ Did you mean to type view_matrix in the descriptive paragraphs? $\endgroup$ – Robin Betts Jul 15 at 13:05
  • $\begingroup$ @Robin Actually, no. As stated in the question, I'm still confused about perspective_matrix, window_matrix and view_matrix. The code works view perspective_matrix, although I don't know why. If you could clarify, that would be great. $\endgroup$ – Leander Jul 15 at 13:12
  • 1
    $\begingroup$ Following (as far as I can see) exactly the conventions described here, viewing down -Z, view_matrix is the xform from world space to viewpoint space (the inverse of the world xform of the viewpoint).. what window_matrix is depends on whether your view is orthogonal or perspective, and in either case gives the xform from the current window-shaped frustum to a canonical view volume, a cube -1 to 1 in X,Y and Z, viewpoint at 0. The perspective_matrix gives the 1st xform followed by the 2nd. $\endgroup$ – Robin Betts Jul 16 at 15:57

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.