From 4fada2e10f925100956f47e2ff994471bc844db4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Aug 2017 15:12:47 +1000 Subject: Manipulator: Use 2D manipulators in the 3D view Also split update flag into draw-steps, since drawing 3D manipulators was tagging 2D as being refreshed. --- source/blender/draw/intern/draw_view.c | 26 ++++++++++- .../manipulator_types/cage2d_manipulator.c | 3 +- .../manipulators/WM_manipulator_types.h | 2 +- .../manipulators/intern/wm_manipulator_intern.h | 2 +- .../manipulators/intern/wm_manipulator_map.c | 51 +++++++++++++++------- 5 files changed, 63 insertions(+), 21 deletions(-) (limited to 'source') diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index e58f7cfbd29..67bb781562e 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -728,5 +728,29 @@ void DRW_draw_manipulator(void) /* draw depth culled manipulators - manipulators need to be updated *after* view matrix was set up */ /* TODO depth culling manipulators is not yet supported, just drawing _3D here, should * later become _IN_SCENE (and draw _3D separate) */ - WM_manipulatormap_draw(ar->manipulator_map, draw_ctx->evil_C, WM_MANIPULATORMAP_DRAWSTEP_3D); + WM_manipulatormap_draw( + ar->manipulator_map, draw_ctx->evil_C, + WM_MANIPULATORMAP_DRAWSTEP_3D); + + /* We may want to split this into a separate pass. + * or maintain a stage in the draw manager where all pixel-space drawing happens. */ + { + float original_proj[4][4]; + gpuGetProjectionMatrix(original_proj); + wmOrtho2_region_pixelspace(ar); + + gpuPushMatrix(); + gpuLoadIdentity(); + + glDepthMask(GL_FALSE); + + WM_manipulatormap_draw( + ar->manipulator_map, draw_ctx->evil_C, + WM_MANIPULATORMAP_DRAWSTEP_2D); + + glDepthMask(GL_TRUE); + + gpuPopMatrix(); + gpuLoadProjectionMatrix(original_proj); + } } diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c index bd45232c56f..0f33a6abe09 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c @@ -702,9 +702,8 @@ static void MANIPULATOR_WT_cage_2d(wmManipulatorType *wt) RNA_def_float_vector(wt->srna, "dimensions", 2, unit_v2, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX); RNA_def_enum_flag(wt->srna, "transform", rna_enum_transform, 0, "Transform Options", ""); - WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 1); + WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 2); WM_manipulatortype_target_property_def(wt, "scale", PROP_FLOAT, 2); - WM_manipulatortype_target_property_def(wt, "scale_uniform", PROP_FLOAT, 1); } void ED_manipulatortypes_cage_2d(void) diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h index 5b74414cc0b..52b3c5d85dd 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h @@ -206,7 +206,6 @@ typedef struct wmManipulatorProperty { wmManipulatorPropertyFnSet value_set_fn; wmManipulatorPropertyFnRangeGet range_get_fn; wmManipulatorPropertyFnFree free_fn; - const struct bContext *context; void *user_data; } custom_func; } wmManipulatorProperty; @@ -376,5 +375,6 @@ typedef enum eWM_ManipulatorMapDrawStep { * Note that these are expected to be 3D manipulators too. */ WM_MANIPULATORMAP_DRAWSTEP_IN_SCENE, } eWM_ManipulatorMapDrawStep; +#define WM_MANIPULATORMAP_DRAWSTEP_MAX 3 #endif /* __WM_MANIPULATOR_TYPES_H__ */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h index bed87a77b3d..06578fee555 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h @@ -97,7 +97,7 @@ struct wmManipulatorMap { ListBase groups; /* wmManipulatorGroup */ /* private, update tagging (enum defined in C source). */ - char update_flag; + char update_flag[WM_MANIPULATORMAP_DRAWSTEP_MAX]; /** * \brief Manipulator map runtime context diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c index 54034333782..b9946d54cee 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c @@ -167,7 +167,7 @@ wmManipulatorMap *WM_manipulatormap_new_from_type( mmap = MEM_callocN(sizeof(wmManipulatorMap), "ManipulatorMap"); mmap->type = mmap_type; - mmap->update_flag = MANIPULATORMAP_IS_PREPARE_DRAW | MANIPULATORMAP_IS_REFRESH_CALLBACK; + WM_manipulatormap_tag_refresh(mmap); /* create all manipulator-groups for this manipulator-map. We may create an empty one * too in anticipation of manipulators from operators etc */ @@ -259,15 +259,19 @@ static GHash *WM_manipulatormap_manipulator_hash_new( void WM_manipulatormap_tag_refresh(wmManipulatorMap *mmap) { if (mmap) { - mmap->update_flag |= ( - MANIPULATORMAP_IS_PREPARE_DRAW | - MANIPULATORMAP_IS_REFRESH_CALLBACK); + /* We might want only to refresh some, for tag all steps. */ + for (int i = 0; i < WM_MANIPULATORMAP_DRAWSTEP_MAX; i++) { + mmap->update_flag[i] |= ( + MANIPULATORMAP_IS_PREPARE_DRAW | + MANIPULATORMAP_IS_REFRESH_CALLBACK); + } } } static bool manipulator_prepare_drawing( wmManipulatorMap *mmap, wmManipulator *mpr, - const bContext *C, ListBase *draw_manipulators) + const bContext *C, ListBase *draw_manipulators, + const eWM_ManipulatorMapDrawStep drawstep) { int do_draw = wm_manipulator_is_visible(mpr); if (do_draw == 0) { @@ -276,7 +280,7 @@ static bool manipulator_prepare_drawing( else { if (do_draw & WM_MANIPULATOR_IS_VISIBLE_UPDATE) { /* hover manipulators need updating, even if we don't draw them */ - wm_manipulator_update(mpr, C, (mmap->update_flag & MANIPULATORMAP_IS_PREPARE_DRAW) != 0); + wm_manipulator_update(mpr, C, (mmap->update_flag[drawstep] & MANIPULATORMAP_IS_PREPARE_DRAW) != 0); } if (do_draw & WM_MANIPULATOR_IS_VISIBLE_DRAW) { BLI_addhead(draw_manipulators, BLI_genericNodeN(mpr)); @@ -302,8 +306,8 @@ static void manipulatormap_prepare_drawing( /* only active manipulator needs updating */ if (mpr_modal) { if ((mpr_modal->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_DRAW_MODAL_ALL) == 0) { - if (manipulator_prepare_drawing(mmap, mpr_modal, C, draw_manipulators)) { - mmap->update_flag &= ~MANIPULATORMAP_IS_PREPARE_DRAW; + if (manipulator_prepare_drawing(mmap, mpr_modal, C, draw_manipulators, drawstep)) { + mmap->update_flag[drawstep] &= ~MANIPULATORMAP_IS_PREPARE_DRAW; } /* don't draw any other manipulators */ return; @@ -322,7 +326,7 @@ static void manipulatormap_prepare_drawing( wm_manipulatorgroup_ensure_initialized(mgroup, C); /* update data if needed */ /* XXX weak: Manipulator-group may skip refreshing if it's invisible (map gets untagged nevertheless) */ - if ((mmap->update_flag & MANIPULATORMAP_IS_REFRESH_CALLBACK) && mgroup->type->refresh) { + if ((mmap->update_flag[drawstep] & MANIPULATORMAP_IS_REFRESH_CALLBACK) && mgroup->type->refresh) { mgroup->type->refresh(C, mgroup); /* cleared below */ } @@ -332,11 +336,11 @@ static void manipulatormap_prepare_drawing( } for (wmManipulator *mpr = mgroup->manipulators.first; mpr; mpr = mpr->next) { - manipulator_prepare_drawing(mmap, mpr, C, draw_manipulators); + manipulator_prepare_drawing(mmap, mpr, C, draw_manipulators, drawstep); } } - mmap->update_flag &= + mmap->update_flag[drawstep] &= ~(MANIPULATORMAP_IS_REFRESH_CALLBACK | MANIPULATORMAP_IS_PREPARE_DRAW); } @@ -551,24 +555,39 @@ wmManipulator *wm_manipulatormap_highlight_find( for (wmManipulatorGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { if (wm_manipulatorgroup_is_visible(mgroup, C)) { if (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) { - if ((mmap->update_flag & MANIPULATORMAP_IS_REFRESH_CALLBACK) && mgroup->type->refresh) { + if ((mmap->update_flag[WM_MANIPULATORMAP_DRAWSTEP_3D] & MANIPULATORMAP_IS_REFRESH_CALLBACK) && + mgroup->type->refresh) + { mgroup->type->refresh(C, mgroup); /* cleared below */ } wm_manipulatorgroup_intersectable_manipulators_to_list(mgroup, &visible_3d_manipulators); } - else if ((mpr = wm_manipulatorgroup_find_intersected_mainpulator(mgroup, C, event, r_part))) { - break; + else { + if ((mmap->update_flag[WM_MANIPULATORMAP_DRAWSTEP_2D] & MANIPULATORMAP_IS_REFRESH_CALLBACK) && + mgroup->type->refresh) + { + mgroup->type->refresh(C, mgroup); + /* cleared below */ + } + + if ((mpr = wm_manipulatorgroup_find_intersected_mainpulator(mgroup, C, event, r_part))) { + break; + } } } } if (!BLI_listbase_is_empty(&visible_3d_manipulators)) { - mpr = manipulator_find_intersected_3d(C, event->mval, &visible_3d_manipulators, r_part); + /* 2D manipulators get priority. */ + if (mpr == NULL) { + mpr = manipulator_find_intersected_3d(C, event->mval, &visible_3d_manipulators, r_part); + } BLI_freelistN(&visible_3d_manipulators); } - mmap->update_flag &= ~MANIPULATORMAP_IS_REFRESH_CALLBACK; + mmap->update_flag[WM_MANIPULATORMAP_DRAWSTEP_3D] &= ~MANIPULATORMAP_IS_REFRESH_CALLBACK; + mmap->update_flag[WM_MANIPULATORMAP_DRAWSTEP_2D] &= ~MANIPULATORMAP_IS_REFRESH_CALLBACK; return mpr; } -- cgit v1.2.3