31static bool ndof_orbit_center_is_used_no_viewport();
42static bool is_bounding_box_in_frustum(
const float projmat[4][4],
53 HAS_TRANSLATE = (1 << 0),
54 HAS_ROTATE = (1 << 0),
57static bool ndof_has_translate(
const wmNDOFMotionData &ndof,
64static bool ndof_has_translate_pan(
const wmNDOFMotionData &ndof,
71static bool ndof_has_rotate(
const wmNDOFMotionData &ndof,
const RegionView3D *rv3d)
79static float view3d_ndof_pan_speed_calc_ex(
RegionView3D *rv3d,
const float depth_pt[3])
90static float view3d_ndof_pan_speed_calc_from_dist(
RegionView3D *rv3d,
const float dist)
106 return view3d_ndof_pan_speed_calc_ex(rv3d, tvec);
109static float view3d_ndof_pan_speed_calc(
RegionView3D *rv3d)
119 return view3d_ndof_pan_speed_calc_ex(rv3d, tvec);
128static void view3d_ndof_pan_zoom(
const wmNDOFMotionData &ndof,
131 const bool has_translate,
136 if (has_translate ==
false && has_zoom ==
false) {
140 blender::float3 pan_vec = WM_event_ndof_translation_get_for_navigation(ndof);
146 float zoom_distance = rv3d->
dist * ndof.time_delta * pan_vec[2];
147 rv3d->
dist += zoom_distance;
168 const float speed = view3d_ndof_pan_speed_calc(rv3d);
169 pan_vec *= speed * ndof.time_delta;
190static void view3d_ndof_orbit(
const wmNDOFMotionData &ndof,
194 const bool apply_dyn_ofs)
211 float angle, quat[4];
212 float xvec[3] = {1, 0, 0};
213 float yvec[3] = {0, 1, 0};
232 if (yvec[2] < 0.0f) {
248 float angle = ndof.time_delta *
249 WM_event_ndof_rotation_get_axis_angle_for_navigation(ndof, axis);
266 if (ndof_orbit_center_is_used(v3d, rv3d)) {
281void view3d_ndof_fly(
const wmNDOFMotionData &ndof,
284 const bool use_precision,
285 const short protectflag,
286 bool *r_has_translate,
289 bool has_translate = ndof_has_translate(ndof, v3d, rv3d);
290 bool has_rotate = ndof_has_rotate(ndof, rv3d);
300 float speed = view3d_ndof_pan_speed_calc_from_dist(rv3d, 1.0f);
307 blender::float3 trans = (speed * ndof.time_delta) * WM_event_ndof_translation_get(ndof);
308 trans_orig_y = trans[1];
319 trans[2] = trans_orig_y;
339 has_translate =
true;
342 has_translate =
false;
349 float angle = ndof.time_delta * WM_event_ndof_rotation_get_axis_angle(ndof, axis);
368 float view_horizon[3] = {1.0f, 0.0f, 0.0f};
369 float view_direction[3] = {0.0f, 0.0f, -1.0f};
395 *r_has_translate = has_translate;
396 *r_has_rotate = has_rotate;
405static bool ndof_orbit_center_is_used_no_viewport()
422 if (!ndof_orbit_center_is_used_no_viewport()) {
432 "This test should not run from a camera view unless the camera is locked to the viewport");
464static std::optional<float3> ndof_orbit_center_calc_from_bounds(Depsgraph *
depsgraph,
468 std::optional<Bounds<float3>> bounding_box = std::nullopt;
471 bool do_zoom =
false;
478 if (bounding_box.has_value()) {
482 bounding_box->scale_from_center(
float3(0.8));
484 if (is_bounding_box_in_frustum(rv3d->
persmat, *bounding_box)) {
488 const float3 center = bounding_box->center();
489 if (ndof_orbit_center_is_valid(rv3d, center)) {
497static float ndof_read_zbuf_rect(
ARegion *region,
const rcti &rect,
int r_xy[2])
525static std::optional<float3> ndof_get_min_depth_pt(
ARegion *region,
const rcti &rect)
528 const float depth_near = ndof_read_zbuf_rect(region, rect,
xy);
536static std::optional<float3> ndof_orbit_center_calc_from_zbuf(Depsgraph *
depsgraph,
544 sample_rect.
xmin = 0.3f * region->
winx;
545 sample_rect.
xmax = 0.7f * region->
winx;
546 sample_rect.
ymin = 0.2f * region->
winy;
547 sample_rect.
ymax = 0.6f * region->
winy;
550 int view_center[2] = {region->
winx / 2, region->
winy / 2};
554 const std::optional<float3> min_depth_pt = ndof_get_min_depth_pt(region, sample_rect);
566 const float scale_margin = 1.05f;
596static std::optional<float3> ndof_orbit_center_calc(Depsgraph *
depsgraph,
615 std::optional<float3> center_test = ndof_orbit_center_calc_from_bounds(
depsgraph, area, region);
616 if (!center_test.has_value()) {
617 center_test = ndof_orbit_center_calc_from_zbuf(
depsgraph, area, region);
633 const wmNDOFMotionData &ndof)
646 blender::float3 pan_vec = WM_event_ndof_translation_get_for_navigation(ndof);
648 const bool has_translate = !
is_zero_v2(pan_vec);
649 const bool has_zoom = pan_vec[2] != 0.0f;
651 pan_vec *= ndof.time_delta;
664 if (!(has_translate || has_zoom)) {
668 bool changed =
false;
710 const wmNDOFMotionData &ndof = *
static_cast<const wmNDOFMotionData *
>(
event->customdata);
716 const bool has_rotation = ndof_has_rotate(ndof, rv3d);
719 ndof_has_translate(ndof, v3d, rv3d);
720 const bool has_zoom = (rv3d->
is_persp ==
false) && WM_event_ndof_translation_has_zoom(ndof);
722 if (has_translate || has_zoom) {
723 view3d_ndof_pan_zoom(ndof, vod->
area, vod->
region, has_translate, has_zoom);
724 xform_flag |= HAS_TRANSLATE;
728 view3d_ndof_orbit(ndof, vod->
area, vod->
region, vod,
true);
729 xform_flag |= HAS_ROTATE;
736 v3d, rv3d,
C, xform_flag & HAS_ROTATE, xform_flag & HAS_TRANSLATE);
756 ot->name =
"NDOF Orbit View";
757 ot->description =
"Orbit the view using the 3D mouse";
758 ot->idname = ViewOpsType_ndof_orbit.idname;
761 ot->invoke = ndof_orbit_invoke;
783 const wmNDOFMotionData &ndof = *
static_cast<const wmNDOFMotionData *
>(
event->customdata);
786 const wmOperatorStatus camera_retval = view3d_ndof_cameraview_pan_zoom(vod, ndof);
788 return camera_retval;
803 if (ndof_orbit_center_is_used(v3d, rv3d)) {
805 if (std::optional<float3> center_test = ndof_orbit_center_calc(
823 const bool has_translate = ndof_has_translate(ndof, v3d, rv3d);
824 const bool has_zoom = WM_event_ndof_translation_has_zoom(ndof) &&
827 if (has_translate || has_zoom) {
828 view3d_ndof_pan_zoom(ndof, vod->
area, vod->
region, has_translate,
true);
829 xform_flag |= HAS_TRANSLATE;
838 const bool has_rotation = ndof_has_rotate(ndof, rv3d);
839 bool has_translate, has_zoom;
841 if (is_orbit_around_pivot) {
843 has_translate = ndof_has_translate_pan(ndof, v3d, rv3d);
844 has_zoom = WM_event_ndof_translation_has_zoom(ndof);
848 has_translate = ndof_has_translate(ndof, v3d, rv3d);
854 const float dist_backup = rv3d->
dist;
855 if (!is_orbit_around_pivot) {
858 view3d_ndof_orbit(ndof, vod->
area, vod->
region, vod, is_orbit_around_pivot);
859 xform_flag |= HAS_ROTATE;
860 if (!is_orbit_around_pivot) {
865 if (has_translate || has_zoom) {
866 view3d_ndof_pan_zoom(ndof, vod->
area, vod->
region, has_translate, has_zoom);
867 xform_flag |= HAS_TRANSLATE;
874 v3d, rv3d,
C, xform_flag & HAS_ROTATE, xform_flag & HAS_TRANSLATE);
894 ot->name =
"NDOF Orbit View with Zoom";
895 ot->description =
"Orbit and zoom the view using the 3D mouse";
896 ot->idname = ViewOpsType_ndof_orbit_zoom.idname;
899 ot->invoke = ndof_orbit_zoom_invoke;
921 const wmNDOFMotionData &ndof = *
static_cast<const wmNDOFMotionData *
>(
event->customdata);
924 const wmOperatorStatus camera_retval = view3d_ndof_cameraview_pan_zoom(vod, ndof);
926 return camera_retval;
936 const bool has_translate = ndof_has_translate(ndof, v3d, rv3d);
937 const bool has_zoom = (rv3d->
is_persp ==
false) && WM_event_ndof_translation_has_zoom(ndof);
942 if (!(has_translate || has_zoom)) {
951 if (has_translate || has_zoom) {
952 view3d_ndof_pan_zoom(ndof, area, region, has_translate, has_zoom);
953 xform_flag |= HAS_TRANSLATE;
979 ot->name =
"NDOF Pan View";
980 ot->description =
"Pan the view with the 3D mouse";
981 ot->idname = ViewOpsType_ndof_pan.idname;
984 ot->invoke = ndof_pan_invoke;
1009 const uint8_t ndof_navigation_mode_backup =
U.ndof_navigation_mode;
1012 ret = ndof_orbit_zoom_invoke_impl(
C, vod, event,
nullptr);
1014 U.ndof_navigation_mode = ndof_navigation_mode_backup;
1031 ot->name =
"NDOF Transform View";
1032 ot->description =
"Pan and rotate the view with the 3D mouse";
1033 ot->idname = ViewOpsType_ndof_all.idname;
1036 ot->invoke = ndof_all_invoke;
1045 "VIEW3D_OT_ndof_orbit",
1047 ndof_orbit_invoke_impl,
1053 "VIEW3D_OT_ndof_orbit_zoom",
1055 ndof_orbit_zoom_invoke_impl,
1061 "VIEW3D_OT_ndof_pan",
1063 ndof_pan_invoke_impl,
1069 "VIEW3D_OT_ndof_all",
1071 ndof_all_invoke_impl,
bool BKE_layer_collection_has_selected_objects(const Scene *scene, ViewLayer *view_layer, LayerCollection *lc)
#define BLI_assert_msg(a, msg)
MINLINE float max_ff(float a, float b)
#define ISECT_AABB_PLANE_IN_FRONT_ALL
int isect_aabb_planes_v3(const float(*planes)[4], int totplane, const float bbmin[3], const float bbmax[3])
void planes_from_projmat(const float mat[4][4], float left[4], float right[4], float bottom[4], float top[4], float near[4], float far[4])
void mul_mat3_m4_v3(const float mat[4][4], float r[3])
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void axis_angle_to_quat_single(float q[4], char axis, float angle)
void mul_qt_v3(const float q[4], float r[3])
void invert_qt_qt_normalized(float q1[4], const float q2[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE bool is_zero_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT
void BLI_rcti_init_pt_radius(struct rcti *rect, const int xy[2], int size)
#define UNUSED_VARS_NDEBUG(...)
ViewLayer * DEG_get_evaluated_view_layer(const Depsgraph *graph)
Scene * DEG_get_input_scene(const Depsgraph *graph)
#define NDOF_IS_ORBIT_AROUND_CENTER_MODE(userdef)
#define NDOF_PIXELS_PER_SECOND
@ NDOF_NAVIGATION_MODE_FLY
@ NDOF_ORBIT_CENTER_SELECTED
#define RV3D_VIEW_IS_AXIS(view)
#define RV3D_LOCK_FLAGS(rv3d)
bool ED_operator_view3d_active(bContext *C)
void ED_region_tag_redraw(ARegion *region)
void ED_view3d_distance_set(RegionView3D *rv3d, float dist)
bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
bool ED_view3d_distance_set_from_location(RegionView3D *rv3d, const float dist_co[3], float dist_min)
bool ED_view3d_persp_ensure(const Depsgraph *depsgraph, View3D *v3d, ARegion *region)
bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
bool ED_view3d_camera_view_zoom_scale(RegionView3D *rv3d, const float scale)
bool ED_view3d_unproject_v3(const ARegion *region, float regionx, float regiony, float regionz, float world[3])
void ED_view3d_camera_lock_init_ex(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d, bool calc_dist)
bool ED_view3d_camera_view_pan(ARegion *region, const float event_ofs[2])
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3])
bool ED_view3d_camera_lock_autokey(View3D *v3d, RegionView3D *rv3d, bContext *C, bool do_rotate, bool do_translate)
float ED_view3d_dist_soft_min_get(const View3D *v3d, bool use_persp_range)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
BPy_StructRNA * depsgraph
VecBase< float, 3 > float3
ccl_device_inline int4 rect_clip(const int4 a, const int4 b)
struct Object * ob_center
LayerCollection * active_collection
void view3d_depths_rect_create(ARegion *region, rcti *rect, ViewDepths *r_d)
float view3d_depth_near(ViewDepths *d)
float view3d_depth_near_ex(ViewDepths *d, int r_xy[2])
void view3d_boxview_sync(ScrArea *area, ARegion *region)
wmOperatorStatus view3d_navigate_invoke_impl(bContext *C, wmOperator *op, const wmEvent *event, const ViewOpsType *nav_type)
void viewrotate_apply_dyn_ofs(ViewOpsData *vod, const float viewquat_new[4])
bool view3d_calc_point_in_selected_bounds(Depsgraph *depsgraph, struct ViewLayer *view_layer_eval, const View3D *v3d, const blender::float3 &point, const float scale_margin)
@ VIEWOPS_FLAG_ORBIT_SELECT
std::optional< blender::Bounds< blender::float3 > > view3d_calc_minmax_selected(Depsgraph *depsgraph, ScrArea *area, ARegion *region, bool use_all_regions, bool clip_bounds, bool *r_do_zoom)
std::optional< blender::Bounds< blender::float3 > > view3d_calc_minmax_visible(Depsgraph *depsgraph, ScrArea *area, ARegion *region, bool use_all_regions, bool clip_bounds)