Cleanup: split view3d_placement depth & orientation calculation

Split out functionality needed for preview plane drawing.
This commit is contained in:
Campbell Barton
2020-11-12 16:15:02 +11:00
parent 934c2c8ac5
commit 89c8b074e7

View File

@@ -609,13 +609,129 @@ static void draw_primitive_view(const struct bContext *C, ARegion *UNUSED(region
/** \} */
/* -------------------------------------------------------------------- */
/** \name Calculate The Initial Placement Plane
*
* Use by both the operator and placement cursor.
* \{ */
static void view3d_interactive_add_calc_plane(bContext *C,
Scene *scene,
View3D *v3d,
ARegion *region,
wmGizmo *snap_gizmo,
const float mval_fl[2],
const enum ePlace_Depth plane_depth,
const enum ePlace_Orient plane_orient,
const int plane_axis,
float r_co_src[3],
float r_matrix_orient[3][3])
{
const RegionView3D *rv3d = region->regiondata;
ED_transform_calc_orientation_from_type(C, r_matrix_orient);
SnapObjectContext *snap_context = NULL;
bool snap_context_free = false;
/* Set the orientation. */
if ((plane_orient == PLACE_ORIENT_SURFACE) || (plane_depth == PLACE_DEPTH_SURFACE)) {
snap_context = (snap_gizmo ?
ED_gizmotypes_snap_3d_context_ensure(scene, region, v3d, snap_gizmo) :
NULL);
if (snap_context == NULL) {
snap_context = ED_transform_snap_object_context_create_view3d(scene, 0, region, v3d);
snap_context_free = true;
}
}
if (plane_orient == PLACE_ORIENT_SURFACE) {
float matrix_orient_surface[3][3];
/* Use the snap normal as a fallback in case the cursor isn't over a surface
* but snapping is enabled. */
float normal_fallback[3];
bool use_normal_fallback = snap_gizmo ?
idp_snap_normal_from_gizmo(snap_gizmo, normal_fallback) :
false;
if ((snap_context != NULL) &&
idp_poject_surface_normal(snap_context,
CTX_data_ensure_evaluated_depsgraph(C),
mval_fl,
use_normal_fallback ? r_matrix_orient : NULL,
use_normal_fallback ? normal_fallback : NULL,
matrix_orient_surface)) {
copy_m3_m3(r_matrix_orient, matrix_orient_surface);
}
}
const bool is_snap_found = snap_gizmo ? idp_snap_point_from_gizmo(snap_gizmo, r_co_src) : false;
if (is_snap_found) {
/* pass */
}
else {
bool use_depth_fallback = true;
if (plane_depth == PLACE_DEPTH_CURSOR_VIEW) {
/* View plane. */
ED_view3d_win_to_3d(v3d, region, scene->cursor.location, mval_fl, r_co_src);
use_depth_fallback = false;
}
else if (plane_depth == PLACE_DEPTH_SURFACE) {
if ((snap_context != NULL) &&
ED_transform_snap_object_project_view3d(snap_context,
CTX_data_ensure_evaluated_depsgraph(C),
SCE_SNAP_MODE_FACE,
&(const struct SnapObjectParams){
.snap_select = SNAP_ALL,
.use_object_edit_cage = true,
},
mval_fl,
NULL,
NULL,
r_co_src,
NULL)) {
use_depth_fallback = false;
}
}
/* Use as fallback to surface. */
if (use_depth_fallback || (plane_depth == PLACE_DEPTH_CURSOR_PLANE)) {
/* Cursor plane. */
float plane[4];
plane_from_point_normal_v3(plane, scene->cursor.location, r_matrix_orient[plane_axis]);
if (ED_view3d_win_to_3d_on_plane(region, plane, mval_fl, false, r_co_src)) {
use_depth_fallback = false;
}
/* Even if the calculation works, it's possible the point found is behind the view. */
if (rv3d->is_persp) {
float dir[3];
sub_v3_v3v3(dir, rv3d->viewinv[3], r_co_src);
if (dot_v3v3(dir, rv3d->viewinv[2]) < v3d->clip_start) {
use_depth_fallback = true;
}
}
}
if (use_depth_fallback) {
float co_depth[3];
/* Fallback to view center. */
negate_v3_v3(co_depth, rv3d->ofs);
ED_view3d_win_to_3d(v3d, region, co_depth, mval_fl, r_co_src);
}
}
if (snap_context_free) {
ED_transform_snap_object_context_destroy(snap_context);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Add Object Modal Operator
* \{ */
/**
*
* */
static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -628,8 +744,6 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
struct InteractivePlaceData *ipd = op->customdata;
RegionView3D *rv3d = ipd->region->regiondata;
/* Assign snap gizmo which is may be used as part of the tool. */
{
wmGizmoMap *gzmap = ipd->region->gizmo_map;
@@ -639,45 +753,19 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
}
}
SnapObjectContext *snap_context = NULL;
bool snap_context_free = false;
if ((plane_orient == PLACE_ORIENT_SURFACE) || (plane_depth == PLACE_DEPTH_SURFACE)) {
/* Need# snap_context */
if (ipd->snap_gizmo) {
snap_context = ED_gizmotypes_snap_3d_context_ensure(
ipd->scene, ipd->region, ipd->v3d, ipd->snap_gizmo);
}
else {
snap_context = ED_transform_snap_object_context_create_view3d(
ipd->scene, 0, ipd->region, ipd->v3d);
snap_context_free = true;
}
}
ipd->launch_event = WM_userdef_event_type_from_keymap_type(event->type);
ED_transform_calc_orientation_from_type(C, ipd->matrix_orient);
/* Set the orientation. */
if (snap_context && (plane_orient == PLACE_ORIENT_SURFACE)) {
float matrix_orient_surface[3][3];
/* Use the snap normal as a fallback in case the cursor isn't over a surface
* but snapping is enabled. */
float normal_fallback[3];
bool use_normal_fallback = ipd->snap_gizmo ?
idp_snap_normal_from_gizmo(ipd->snap_gizmo, normal_fallback) :
false;
if (idp_poject_surface_normal(snap_context,
CTX_data_ensure_evaluated_depsgraph(C),
mval_fl,
use_normal_fallback ? ipd->matrix_orient : NULL,
use_normal_fallback ? normal_fallback : NULL,
matrix_orient_surface)) {
copy_m3_m3(ipd->matrix_orient, matrix_orient_surface);
}
}
view3d_interactive_add_calc_plane(C,
ipd->scene,
ipd->v3d,
ipd->region,
ipd->snap_gizmo,
mval_fl,
plane_depth,
plane_orient,
plane_axis,
ipd->co_src,
ipd->matrix_orient);
ipd->orient_axis = plane_axis;
ipd->is_centered_init = (plane_origin == PLACE_ORIGIN_CENTER);
@@ -685,6 +773,23 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
ipd->step[1].is_centered = ipd->is_centered_init;
ipd->step_index = STEP_BASE;
plane_from_point_normal_v3(ipd->step[0].plane, ipd->co_src, ipd->matrix_orient[plane_axis]);
copy_v3_v3(ipd->step[0].co_dst, ipd->co_src);
ipd->is_snap_invert = ipd->snap_gizmo ? ED_gizmotypes_snap_3d_invert_snap_get(ipd->snap_gizmo) :
false;
{
const ToolSettings *ts = ipd->scene->toolsettings;
ipd->use_snap = (ipd->is_snap_invert == !(ts->snap_flag & SCE_SNAP));
}
ipd->draw_handle_view = ED_region_draw_cb_activate(
ipd->region->type, draw_primitive_view, ipd, REGION_DRAW_POST_VIEW);
ED_region_tag_redraw(ipd->region);
/* Setup the primitive type. */
{
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "primitive_type");
if (RNA_property_is_set(op->ptr, prop)) {
@@ -719,90 +824,6 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
}
}
}
UNUSED_VARS(C, event);
ipd->draw_handle_view = ED_region_draw_cb_activate(
ipd->region->type, draw_primitive_view, ipd, REGION_DRAW_POST_VIEW);
ED_region_tag_redraw(ipd->region);
plane_from_point_normal_v3(
ipd->step[0].plane, ipd->scene->cursor.location, ipd->matrix_orient[ipd->orient_axis]);
const bool is_snap_found = ipd->snap_gizmo ?
idp_snap_point_from_gizmo(ipd->snap_gizmo, ipd->co_src) :
false;
ipd->is_snap_invert = ipd->snap_gizmo ? ED_gizmotypes_snap_3d_invert_snap_get(ipd->snap_gizmo) :
false;
{
const ToolSettings *ts = ipd->scene->toolsettings;
ipd->use_snap = (ipd->is_snap_invert == !(ts->snap_flag & SCE_SNAP));
}
if (is_snap_found) {
/* pass */
}
else {
bool use_depth_fallback = true;
if (plane_depth == PLACE_DEPTH_CURSOR_VIEW) {
/* View plane. */
ED_view3d_win_to_3d(
ipd->v3d, ipd->region, ipd->scene->cursor.location, mval_fl, ipd->co_src);
use_depth_fallback = false;
}
else if (snap_context && (plane_depth == PLACE_DEPTH_SURFACE)) {
if (ED_transform_snap_object_project_view3d(snap_context,
CTX_data_ensure_evaluated_depsgraph(C),
SCE_SNAP_MODE_FACE,
&(const struct SnapObjectParams){
.snap_select = SNAP_ALL,
.use_object_edit_cage = true,
},
mval_fl,
NULL,
NULL,
ipd->co_src,
NULL)) {
use_depth_fallback = false;
}
}
/* Use as fallback to surface. */
if (use_depth_fallback || (plane_depth == PLACE_DEPTH_CURSOR_PLANE)) {
/* Cursor plane. */
float plane[4];
plane_from_point_normal_v3(
plane, ipd->scene->cursor.location, ipd->matrix_orient[ipd->orient_axis]);
if (ED_view3d_win_to_3d_on_plane(ipd->region, plane, mval_fl, false, ipd->co_src)) {
use_depth_fallback = false;
}
/* Even if the calculation works, it's possible the point found is behind the view. */
if (rv3d->is_persp) {
float dir[3];
sub_v3_v3v3(dir, rv3d->viewinv[3], ipd->co_src);
if (dot_v3v3(dir, rv3d->viewinv[2]) < ipd->v3d->clip_start) {
use_depth_fallback = true;
}
}
}
if (use_depth_fallback) {
float co_depth[3];
/* Fallback to view center. */
negate_v3_v3(co_depth, rv3d->ofs);
ED_view3d_win_to_3d(ipd->v3d, ipd->region, co_depth, mval_fl, ipd->co_src);
}
}
plane_from_point_normal_v3(
ipd->step[0].plane, ipd->co_src, ipd->matrix_orient[ipd->orient_axis]);
copy_v3_v3(ipd->step[0].co_dst, ipd->co_src);
if (snap_context_free) {
ED_transform_snap_object_context_destroy(snap_context);
}
}
static int view3d_interactive_add_invoke(bContext *C, wmOperator *op, const wmEvent *event)