This commit implements described in the #104573. The goal is to fix the confusion of the submodule hashes change, which are not ideal for any of the supported git-module configuration (they are either always visible causing confusion, or silently staged and committed, also causing confusion). This commit replaces submodules with a checkout of addons and addons_contrib, covered by the .gitignore, and locale and developer tools are moved to the main repository. This also changes the paths: - /release/scripts are moved to the /scripts - /source/tools are moved to the /tools - /release/datafiles/locale is moved to /locale This is done to avoid conflicts when using bisect, and also allow buildbot to automatically "recover" wgen building older or newer branches/patches. Running `make update` will initialize the local checkout to the changed repository configuration. Another aspect of the change is that the make update will support Github style of remote organization (origin remote pointing to thy fork, upstream remote pointing to the upstream blender/blender.git). Pull Request #104755
180 lines
6.0 KiB
Python
180 lines
6.0 KiB
Python
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
__all__ = (
|
|
"region_2d_to_vector_3d",
|
|
"region_2d_to_origin_3d",
|
|
"region_2d_to_location_3d",
|
|
"location_3d_to_region_2d",
|
|
)
|
|
|
|
|
|
def region_2d_to_vector_3d(region, rv3d, coord):
|
|
"""
|
|
Return a direction vector from the viewport at the specific 2d region
|
|
coordinate.
|
|
|
|
: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.
|
|
:type rv3d: :class:`bpy.types.RegionView3D`
|
|
:arg coord: 2d coordinates relative to the region:
|
|
(event.mouse_region_x, event.mouse_region_y) for example.
|
|
:type coord: 2d vector
|
|
:return: normalized 3d vector.
|
|
:rtype: :class:`mathutils.Vector`
|
|
"""
|
|
from mathutils import Vector
|
|
|
|
viewinv = rv3d.view_matrix.inverted()
|
|
if rv3d.is_perspective:
|
|
persinv = rv3d.perspective_matrix.inverted()
|
|
|
|
out = Vector((
|
|
(2.0 * coord[0] / region.width) - 1.0,
|
|
(2.0 * coord[1] / region.height) - 1.0,
|
|
-0.5
|
|
))
|
|
|
|
w = out.dot(persinv[3].xyz) + persinv[3][3]
|
|
|
|
view_vector = ((persinv @ out) / w) - viewinv.translation
|
|
else:
|
|
view_vector = -viewinv.col[2].xyz
|
|
|
|
view_vector.normalize()
|
|
|
|
return view_vector
|
|
|
|
|
|
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.
|
|
:type rv3d: :class:`bpy.types.RegionView3D`
|
|
: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`
|
|
"""
|
|
viewinv = rv3d.view_matrix.inverted()
|
|
|
|
if rv3d.is_perspective:
|
|
origin_start = viewinv.translation.copy()
|
|
else:
|
|
persmat = rv3d.perspective_matrix.copy()
|
|
dx = (2.0 * coord[0] / region.width) - 1.0
|
|
dy = (2.0 * coord[1] / region.height) - 1.0
|
|
persinv = persmat.inverted()
|
|
origin_start = (
|
|
(persinv.col[0].xyz * dx) +
|
|
(persinv.col[1].xyz * dy) +
|
|
persinv.translation
|
|
)
|
|
|
|
if clamp != 0.0:
|
|
if rv3d.view_perspective != 'CAMERA':
|
|
# 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
|
|
|
|
|
|
def region_2d_to_location_3d(region, rv3d, coord, depth_location):
|
|
"""
|
|
Return a 3d location from the region relative 2d coords, aligned with
|
|
*depth_location*.
|
|
|
|
: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.
|
|
:type rv3d: :class:`bpy.types.RegionView3D`
|
|
:arg coord: 2d coordinates relative to the region;
|
|
(event.mouse_region_x, event.mouse_region_y) for example.
|
|
:type coord: 2d vector
|
|
:arg depth_location: the returned vectors depth is aligned with this since
|
|
there is no defined depth with a 2d region input.
|
|
:type depth_location: 3d vector
|
|
:return: normalized 3d vector.
|
|
:rtype: :class:`mathutils.Vector`
|
|
"""
|
|
from mathutils import Vector
|
|
|
|
coord_vec = region_2d_to_vector_3d(region, rv3d, coord)
|
|
depth_location = Vector(depth_location)
|
|
|
|
origin_start = region_2d_to_origin_3d(region, rv3d, coord)
|
|
origin_end = origin_start + coord_vec
|
|
|
|
if rv3d.is_perspective:
|
|
from mathutils.geometry import intersect_line_plane
|
|
viewinv = rv3d.view_matrix.inverted()
|
|
view_vec = viewinv.col[2].copy()
|
|
return intersect_line_plane(
|
|
origin_start,
|
|
origin_end,
|
|
depth_location,
|
|
view_vec, 1,
|
|
)
|
|
else:
|
|
from mathutils.geometry import intersect_point_line
|
|
return intersect_point_line(
|
|
depth_location,
|
|
origin_start,
|
|
origin_end,
|
|
)[0]
|
|
|
|
|
|
def location_3d_to_region_2d(region, rv3d, coord, *, default=None):
|
|
"""
|
|
Return the *region* relative 2d location of a 3d position.
|
|
|
|
: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.
|
|
:type rv3d: :class:`bpy.types.RegionView3D`
|
|
:arg coord: 3d worldspace location.
|
|
:type coord: 3d vector
|
|
:arg default: Return this value if ``coord``
|
|
is behind the origin of a perspective view.
|
|
:return: 2d location
|
|
:rtype: :class:`mathutils.Vector` or ``default`` argument.
|
|
"""
|
|
from mathutils import Vector
|
|
|
|
prj = rv3d.perspective_matrix @ Vector((coord[0], coord[1], coord[2], 1.0))
|
|
if prj.w > 0.0:
|
|
width_half = region.width / 2.0
|
|
height_half = region.height / 2.0
|
|
|
|
return Vector((
|
|
width_half + width_half * (prj.x / prj.w),
|
|
height_half + height_half * (prj.y / prj.w),
|
|
))
|
|
else:
|
|
return default
|