From a4366497db5d30d12f9bbdc6644e5a282383af37 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Jan 2015 05:33:52 +1100 Subject: Fix T43206: region_2d_to_origin_3d has no ortho offset With ortho views the value would be aligned to the 'rv3d->ofs' Now it works in camera ortho & regular ortho views. --- release/scripts/modules/bpy_extras/view3d_utils.py | 29 +++++++++++++++++++++- .../templates_py/operator_modal_view3d_raycast.py | 4 --- source/blender/makesrna/intern/rna_space.c | 11 ++++++-- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/release/scripts/modules/bpy_extras/view3d_utils.py b/release/scripts/modules/bpy_extras/view3d_utils.py index b25024fca9b..56ea1a1b0aa 100644 --- a/release/scripts/modules/bpy_extras/view3d_utils.py +++ b/release/scripts/modules/bpy_extras/view3d_utils.py @@ -63,10 +63,18 @@ def region_2d_to_vector_3d(region, rv3d, coord): return view_vector -def region_2d_to_origin_3d(region, rv3d, coord): +def region_2d_to_origin_3d(region, rv3d, coord, clamp=None): """ Return the 3d view origin from the region relative 2d coords. + .. note:: + + Orthographic views have a less obvious origin, the far clip is used to define the viewport near/far extents. + Since far clip can be a very large value, the result may give with numeric precision issues. + + To avoid this problem, you can optionally clamp the far clip to a smaller value + based on the data you're operating on. + :arg region: region of the 3D viewport, typically bpy.context.region. :type region: :class:`bpy.types.Region` :arg rv3d: 3D region data, typically bpy.context.space_data.region_3d. @@ -74,6 +82,9 @@ def region_2d_to_origin_3d(region, rv3d, coord): :arg coord: 2d coordinates relative to the region; (event.mouse_region_x, event.mouse_region_y) for example. :type coord: 2d vector + :arg clamp: Clamp the maximum far-clip value used. + (negative value will move the offset away from the view_location) + :type clamp: float or None :return: The origin of the viewpoint in 3d space. :rtype: :class:`mathutils.Vector` """ @@ -89,6 +100,22 @@ def region_2d_to_origin_3d(region, rv3d, coord): origin_start = ((persinv.col[0].xyz * dx) + (persinv.col[1].xyz * dy) + viewinv.translation) + + if clamp != 0.0: + winmat = rv3d.window_matrix + # check this isn't a camera + if winmat[2][3] == 0.0: + # this value is scaled to the far clip already + origin_offset = persinv.col[2].xyz + if clamp is not None: + if clamp < 0.0: + origin_offset.negate() + clamp = -clamp + if origin_offset.length > clamp: + origin_offset.length = clamp + + origin_start -= origin_offset + return origin_start diff --git a/release/scripts/templates_py/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py index 1aa13c90ca3..b72b2f76750 100644 --- a/release/scripts/templates_py/operator_modal_view3d_raycast.py +++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py @@ -14,10 +14,6 @@ def main(context, event, ray_max=1000.0): view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord) ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord) - if rv3d.view_perspective == 'ORTHO': - # move ortho origin back - ray_origin = ray_origin - (view_vector * (ray_max / 2.0)) - ray_target = ray_origin + (view_vector * ray_max) def visible_objects_and_duplis(): diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 7ad7f129218..8eed482327d 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2200,13 +2200,20 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "persmat"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* XXX: for now, it's too risky for users to do this */ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); - RNA_def_property_ui_text(prop, "Perspective Matrix", "Current perspective matrix of the 3D region"); + RNA_def_property_ui_text(prop, "Perspective Matrix", + "Current perspective matrix (``window_matrix * view_matrix``)"); + + prop = RNA_def_property(srna, "window_matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "winmat"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(prop, "Window Matrix", "Current window matrix"); prop = RNA_def_property(srna, "view_matrix", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "viewmat"); RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); RNA_def_property_float_funcs(prop, NULL, "rna_RegionView3D_view_matrix_set", NULL); - RNA_def_property_ui_text(prop, "View Matrix", "Current view matrix of the 3D region"); + RNA_def_property_ui_text(prop, "View Matrix", "Current view matrix"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "view_perspective", PROP_ENUM, PROP_NONE); -- cgit v1.2.3