Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-12-15 19:57:20 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-12-15 20:21:30 +0300
commit468ac9031765681cde42e9132d16c799158e7aba (patch)
tree646e5f5e2d090230e02147750f4490115d0a2707 /source/blender
parentc2cc42742d31cd4676e8d3d3ef8340019bf3a307 (diff)
Manipulator: view3d navigation buttons
Added for Blender101 template. Disabled by default, enable as a preference. Exposes rotate, pan, zoom, persp-ortho & camera toggle.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/include/ED_manipulator_library.h1
-rw-r--r--source/blender/editors/manipulator_library/CMakeLists.txt1
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c202
-rw-r--r--source/blender/editors/space_api/spacetypes.c1
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h9
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_navigate.c231
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c305
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c5
11 files changed, 760 insertions, 5 deletions
diff --git a/source/blender/editors/include/ED_manipulator_library.h b/source/blender/editors/include/ED_manipulator_library.h
index 80703321490..7166292147e 100644
--- a/source/blender/editors/include/ED_manipulator_library.h
+++ b/source/blender/editors/include/ED_manipulator_library.h
@@ -33,6 +33,7 @@
/* initialize manipulators */
void ED_manipulatortypes_arrow_2d(void);
void ED_manipulatortypes_arrow_3d(void);
+void ED_manipulatortypes_button_2d(void);
void ED_manipulatortypes_cage_2d(void);
void ED_manipulatortypes_cage_3d(void);
void ED_manipulatortypes_dial_3d(void);
diff --git a/source/blender/editors/manipulator_library/CMakeLists.txt b/source/blender/editors/manipulator_library/CMakeLists.txt
index 9f7df8c6425..86e1bb3b6d7 100644
--- a/source/blender/editors/manipulator_library/CMakeLists.txt
+++ b/source/blender/editors/manipulator_library/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
geometry/geom_dial_manipulator.c
manipulator_types/arrow2d_manipulator.c
manipulator_types/arrow3d_manipulator.c
+ manipulator_types/button2d_manipulator.c
manipulator_types/cage2d_manipulator.c
manipulator_types/cage3d_manipulator.c
manipulator_types/dial3d_manipulator.c
diff --git a/source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c
new file mode 100644
index 00000000000..32c1dbae0a6
--- /dev/null
+++ b/source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c
@@ -0,0 +1,202 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file button2d_manipulator.c
+ * \ingroup wm
+ *
+ * \name Button Manipulator
+ *
+ * 3D Manipulator, also works in 2D views.
+ *
+ * \brief Single click button action for use in manipulator groups.
+ *
+ * Note: currently only very basic icon buttons supported.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+#include "GPU_select.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_interface_icons.h"
+#include "UI_resources.h"
+
+/* own includes */
+#include "../manipulator_geometry.h"
+#include "../manipulator_library_intern.h"
+
+typedef struct ButtonManipulator3D {
+ wmManipulator manipulator;
+ /* Added to 'matrix_basis' when calculating the matrix. */
+ float prop_co[3];
+} ButtonManipulator3D;
+
+#define DIAL_RESOLUTION 32
+
+/* -------------------------------------------------------------------- */
+
+static void button_geom_draw(
+ const wmManipulator *mpr, const float color[4], const bool select)
+{
+ glLineWidth(mpr->line_width);
+
+ Gwn_VertFormat *format = immVertexFormat();
+ uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ immUniformColor4fv(color);
+
+ /* TODO, other draw styles */
+ imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, DIAL_RESOLUTION);
+
+ immUnbindProgram();
+
+ UNUSED_VARS(select);
+}
+
+static void button3d_draw_intern(
+ const bContext *UNUSED(C), wmManipulator *mpr,
+ const bool select, const bool highlight)
+{
+ float color[4];
+ float matrix_final[4][4];
+
+ manipulator_color_get(mpr, highlight, color);
+ WM_manipulator_calc_matrix_final(mpr, matrix_final);
+
+ gpuPushMatrix();
+ gpuMultMatrix(matrix_final);
+
+ glEnable(GL_BLEND);
+ button_geom_draw(mpr, color, select);
+ gpuPopMatrix();
+
+
+ if (select == false) {
+ int icon = RNA_enum_get(mpr->ptr, "icon");
+ if (icon != ICON_NONE) {
+ UI_icon_draw(
+ mpr->matrix_basis[3][0] - (ICON_DEFAULT_WIDTH / 2.0) * U.pixelsize,
+ mpr->matrix_basis[3][1] - (ICON_DEFAULT_HEIGHT / 2.0) * U.pixelsize,
+ icon);
+ }
+ }
+ glDisable(GL_BLEND);
+}
+
+static void manipulator_button_draw_select(const bContext *C, wmManipulator *mpr, int select_id)
+{
+ GPU_select_load_id(select_id);
+ button3d_draw_intern(C, mpr, true, false);
+}
+
+static void manipulator_button_draw(const bContext *C, wmManipulator *mpr)
+{
+ const bool is_highlight = (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) != 0;
+
+ glEnable(GL_BLEND);
+ button3d_draw_intern(C, mpr, false, is_highlight);
+ glDisable(GL_BLEND);
+}
+
+static int manipulator_button_test_select(
+ bContext *C, wmManipulator *mpr, const wmEvent *event)
+{
+ float point_local[2];
+
+ if (0) {
+ /* correct, but unnecessarily slow. */
+ if (manipulator_window_project_2d(
+ C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false)
+ {
+ return -1;
+ }
+ }
+ else {
+ copy_v2_v2(point_local, (float [2]){UNPACK2(event->mval)});
+ sub_v2_v2(point_local, mpr->matrix_basis[3]);
+ mul_v2_fl(point_local, 1.0f / mpr->scale_basis);
+ }
+
+ /* The 'mpr->scale_final' is already applied when projecting. */
+ if (len_squared_v2(point_local) < 1.0f) {
+ return 0;
+ }
+
+ return -1;
+}
+
+static int manipulator_button_cursor_get(wmManipulator *UNUSED(mpr))
+{
+ return BC_HANDCURSOR;
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Button Manipulator API
+ *
+ * \{ */
+
+static void MANIPULATOR_WT_button_2d(wmManipulatorType *wt)
+{
+ /* identifiers */
+ wt->idname = "MANIPULATOR_WT_button_2d";
+
+ /* api callbacks */
+ wt->draw = manipulator_button_draw;
+ wt->draw_select = manipulator_button_draw_select;
+ wt->test_select = manipulator_button_test_select;
+ wt->cursor_get = manipulator_button_cursor_get;
+
+ wt->struct_size = sizeof(ButtonManipulator3D);
+
+ /* rna */
+ PropertyRNA *prop;
+ prop = RNA_def_property(wt->srna, "icon", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_icon_items);
+ RNA_def_property_ui_text(prop, "Icon", "Override automatic icon of the item");
+}
+
+void ED_manipulatortypes_button_2d(void)
+{
+ WM_manipulatortype_append(MANIPULATOR_WT_button_2d);
+}
+
+/** \} */ // Button Manipulator API
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 32f6ac40d12..e417026640e 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -127,6 +127,7 @@ void ED_spacetypes_init(void)
ED_operatortypes_ui();
/* manipulator types */
+ ED_manipulatortypes_button_2d();
ED_manipulatortypes_dial_3d();
ED_manipulatortypes_grab_3d();
ED_manipulatortypes_arrow_2d();
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index de8380aa8bb..11ef781b229 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -64,6 +64,8 @@ set(SRC
view3d_manipulator_empty.c
view3d_manipulator_forcefield.c
view3d_manipulator_lamp.c
+ view3d_manipulator_navigate.c
+ view3d_manipulator_navigate_type.c
view3d_manipulator_ruler.c
view3d_ops.c
view3d_project.c
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 984ab82ee60..3430351b756 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -729,6 +729,9 @@ static void view3d_widgets(void)
WM_manipulatorgrouptype_append(VIEW3D_WGT_ruler);
WM_manipulatortype_append(VIEW3D_WT_ruler_item);
+
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_navigate);
+ WM_manipulatortype_append(VIEW3D_WT_navigate_rotate);
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index a7368a84eb6..ee0b628fdad 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -153,7 +153,7 @@ void draw_object_select(
const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, struct ARegion *ar, View3D *v3d,
Base *base, const short dflag);
-void draw_mesh_object_outline(View3D *v3d, Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]);
+void draw_mesh_object_outline(View3D *v3d, struct Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]);
bool draw_glsl_material(Scene *scene, struct ViewLayer *view_layer, struct Object *ob, View3D *v3d, const char dt);
void draw_object_instance(const struct EvaluationContext *eval_ctx, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]);
@@ -304,7 +304,7 @@ void ED_view3d_cameracontrol_update(
void ED_view3d_cameracontrol_release(
struct View3DCameraControl *vctrl,
const bool restore);
-Object *ED_view3d_cameracontrol_object_get(
+struct Object *ED_view3d_cameracontrol_object_get(
struct View3DCameraControl *vctrl);
/* view3d_toolbar.c */
@@ -338,11 +338,14 @@ void VIEW3D_WGT_camera_view(struct wmManipulatorGroupType *wgt);
void VIEW3D_WGT_force_field(struct wmManipulatorGroupType *wgt);
void VIEW3D_WGT_empty_image(struct wmManipulatorGroupType *wgt);
void VIEW3D_WGT_armature_spline(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_navigate(struct wmManipulatorGroupType *wgt);
void VIEW3D_WGT_ruler(struct wmManipulatorGroupType *wgt);
void VIEW3D_WT_ruler_item(struct wmManipulatorType *wt);
void VIEW3D_OT_ruler_add(struct wmOperatorType *ot);
+void VIEW3D_WT_navigate_rotate(struct wmManipulatorType *wt);
+
/* draw_volume.c */
void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
const float min[3], const float max[3],
@@ -365,7 +368,7 @@ extern bool view3d_camera_border_hack_test;
void VP_legacy_drawcursor(Scene *scene, struct ViewLayer *view_layer, ARegion *ar, View3D *v3d);
void VP_legacy_draw_view_axis(RegionView3D *rv3d, rcti *rect);
void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect);
-void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect);
+void VP_legacy_draw_selected_name(Scene *scene, struct Object *ob, rcti *rect);
void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit);
void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth);
void VP_legacy_view3d_main_region_setup_view(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]);
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_navigate.c b/source/blender/editors/space_view3d/view3d_manipulator_navigate.c
new file mode 100644
index 00000000000..553d3b03687
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_navigate.c
@@ -0,0 +1,231 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_manipulator_navigate.c
+ * \ingroup spview3d
+ */
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_object.h"
+
+#include "DNA_object_types.h"
+
+#include "ED_screen.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_resources.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "view3d_intern.h" /* own include */
+
+/* -------------------------------------------------------------------- */
+/** \name View3D Navigation Manipulator Group
+ * \{ */
+
+/* Offset from screen edge. */
+#define MANIPULATOR_OFFSET_FAC 2.5
+/* Size of main icon. */
+#define MANIPULATOR_SIZE 64
+/* Factor for size of smaller button. */
+#define MANIPULATOR_MINI_FAC 0.4
+/* How much mini buttons offset from the primary. */
+#define MANIPULATOR_MINI_OFFSET_FAC 0.6666f
+
+
+enum {
+ MPR_MOVE = 0,
+ MPR_ROTATE = 1,
+ MPR_ZOOM = 2,
+ /* just buttons */
+ MPR_PERSP_ORTHO = 3,
+ MPR_CAMERA = 4,
+
+ MPR_TOTAL = 5,
+};
+
+struct NavigateManipulatorInfo {
+ const char *opname;
+ const char *manipulator;
+ int icon;
+};
+
+struct NavigateManipulatorInfo g_navigate_params[MPR_TOTAL] = {
+ {
+ .opname = "VIEW3D_OT_move",
+ .manipulator = "MANIPULATOR_WT_button_2d",
+ .icon = ICON_HAND,
+ }, {
+ .opname = "VIEW3D_OT_rotate",
+ .manipulator = "VIEW3D_WT_navigate_rotate",
+ .icon = ICON_NONE,
+ }, {
+ .opname = "VIEW3D_OT_zoom",
+ .manipulator = "MANIPULATOR_WT_button_2d",
+ .icon = ICON_VIEWZOOM,
+ }, {
+ .opname = "VIEW3D_OT_view_persportho",
+ .manipulator = "MANIPULATOR_WT_button_2d",
+ .icon = ICON_MESH_CUBE,
+ }, {
+ .opname = "VIEW3D_OT_viewnumpad",
+ .manipulator = "MANIPULATOR_WT_button_2d",
+ .icon = ICON_OUTLINER_OB_CAMERA,
+ },
+};
+
+struct NavigateWidgetGroup {
+ wmManipulator *mpr_array[MPR_TOTAL];
+ int region_size[2];
+};
+
+static bool WIDGETGROUP_navigate_poll(const bContext *UNUSED(C), wmManipulatorGroupType *UNUSED(wgt))
+{
+ if (U.manipulator_flag & USER_MANIPULATOR_DRAW_NAVIGATE) {
+ return true;
+ }
+ return false;
+
+}
+
+static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ struct NavigateWidgetGroup *navgroup = MEM_callocN(sizeof(struct NavigateWidgetGroup), __func__);
+
+ navgroup->region_size[0] = -1;
+ navgroup->region_size[1] = -1;
+
+ wmOperatorType *ot_viewnumpad = WM_operatortype_find("VIEW3D_OT_viewnumpad", true);
+
+ for (int i = 0; i < MPR_TOTAL; i++) {
+ const struct NavigateManipulatorInfo *info = &g_navigate_params[i];
+ navgroup->mpr_array[i] = WM_manipulator_new(info->manipulator, mgroup, NULL);
+ wmManipulator *mpr = navgroup->mpr_array[i];
+ mpr->flag |= WM_MANIPULATOR_GRAB_CURSOR;
+ RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL);
+ copy_v3_fl(mpr->color, 1.0f);
+ mpr->color[3] = 0.4f;
+
+ /* may be overwritten later */
+ mpr->scale_basis = (MANIPULATOR_SIZE * MANIPULATOR_MINI_FAC) / 2;
+ if (info->icon != ICON_NONE) {
+ RNA_enum_set(mpr->ptr, "icon", info->icon);
+ }
+
+ wmOperatorType *ot = WM_operatortype_find(info->opname, true);
+ WM_manipulator_operator_set(mpr, 0, ot, NULL);
+ }
+
+ {
+ wmManipulator *mpr = navgroup->mpr_array[MPR_CAMERA];
+ PointerRNA *ptr = WM_manipulator_operator_set(mpr, 0, ot_viewnumpad, NULL);
+ RNA_enum_set(ptr, "type", RV3D_VIEW_CAMERA);
+ }
+
+ {
+ wmManipulator *mpr = navgroup->mpr_array[MPR_ROTATE];
+ mpr->scale_basis = MANIPULATOR_SIZE / 2;
+ char mapping[6] = {
+ RV3D_VIEW_LEFT,
+ RV3D_VIEW_RIGHT,
+ RV3D_VIEW_FRONT,
+ RV3D_VIEW_BACK,
+ RV3D_VIEW_BOTTOM,
+ RV3D_VIEW_TOP,
+ };
+
+ for (int part_index = 0; part_index < 6; part_index+= 1) {
+ PointerRNA *ptr = WM_manipulator_operator_set(mpr, mapping[part_index], ot_viewnumpad, NULL);
+ RNA_enum_set(ptr, "type", RV3D_VIEW_FRONT + part_index);
+ }
+ }
+
+ mgroup->customdata = navgroup;
+}
+
+static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct NavigateWidgetGroup *navgroup = mgroup->customdata;
+ ARegion *ar = CTX_wm_region(C);
+ const RegionView3D *rv3d = ar->regiondata;
+
+ for (int i = 0; i < 3; i++) {
+ copy_v3_v3(navgroup->mpr_array[MPR_ROTATE]->matrix_offset[i], rv3d->viewmat[i]);
+ }
+
+ if ((navgroup->region_size[0] == ar->winx) &&
+ (navgroup->region_size[1] == ar->winy))
+ {
+ return;
+ }
+
+ navgroup->region_size[0] = ar->winx;
+ navgroup->region_size[1] = ar->winy;
+
+ const float icon_size = MANIPULATOR_SIZE;
+ const float icon_offset = (icon_size / 2.0) * MANIPULATOR_OFFSET_FAC * U.pixelsize;
+ const float icon_offset_mini = icon_size * MANIPULATOR_MINI_OFFSET_FAC * U.pixelsize;
+ const float co[2] = {ar->winx - icon_offset, ar->winy - icon_offset};
+
+ wmManipulator *mpr;
+ mpr = navgroup->mpr_array[MPR_ROTATE];
+ mpr->matrix_basis[3][0] = co[0];
+ mpr->matrix_basis[3][1] = co[1];
+
+ mpr = navgroup->mpr_array[MPR_MOVE];
+ mpr->matrix_basis[3][0] = co[0] + icon_offset_mini;
+ mpr->matrix_basis[3][1] = co[1] - icon_offset_mini;
+
+ mpr = navgroup->mpr_array[MPR_ZOOM];
+ mpr->matrix_basis[3][0] = co[0] - icon_offset_mini;
+ mpr->matrix_basis[3][1] = co[1] - icon_offset_mini;
+
+ mpr = navgroup->mpr_array[MPR_PERSP_ORTHO];
+ mpr->matrix_basis[3][0] = co[0] + icon_offset_mini;
+ mpr->matrix_basis[3][1] = co[1] + icon_offset_mini;
+
+ mpr = navgroup->mpr_array[MPR_CAMERA];
+ mpr->matrix_basis[3][0] = co[0] - icon_offset_mini;
+ mpr->matrix_basis[3][1] = co[1] + icon_offset_mini;
+}
+
+void VIEW3D_WGT_navigate(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "View3D Navigate";
+ wgt->idname = "VIEW3D_WGT_navigate";
+
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_SCALE);
+
+ wgt->poll = WIDGETGROUP_navigate_poll;
+ wgt->setup = WIDGETGROUP_navigate_setup;
+ wgt->draw_prepare = WIDGETGROUP_navigate_draw_prepare;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c b/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c
new file mode 100644
index 00000000000..d57656ce42a
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_navigate_type.c
@@ -0,0 +1,305 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file view3d_manipulator_navigate_type.c
+ * \ingroup wm
+ *
+ * \name Custom Orientation/Navigation Manipulator for the 3D View
+ *
+ * \brief Simple manipulator to axis and translate.
+ *
+ * matrix_offset is used to store the orientation.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_sort_utils.h"
+
+#include "BKE_context.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+#include "GPU_select.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_resources.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+#include "ED_manipulator_library.h"
+
+#include "view3d_intern.h"
+
+#define DIAL_RESOLUTION 32
+
+#define HANDLE_SIZE 0.33
+
+static void axis_geom_draw(
+ const wmManipulator *mpr, const float color[4], const bool UNUSED(select))
+{
+ glLineWidth(mpr->line_width);
+
+ Gwn_VertFormat *format = immVertexFormat();
+ const uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ /* flip z for reverse */
+ const float cone_coords[5][3] = {
+ {-1, -1, 4},
+ {-1, +1, 4},
+ {+1, +1, 4},
+ {+1, -1, 4},
+ {0, 0, 2},
+ };
+
+ struct {
+ float depth;
+ char index;
+ char axis;
+ char is_pos;
+ } axis_order[6] = {
+ {-mpr->matrix_offset[0][2], 0, 0, false},
+ {+mpr->matrix_offset[0][2], 1, 0, true},
+ {-mpr->matrix_offset[1][2], 2, 1, false},
+ {+mpr->matrix_offset[1][2], 3, 1, true},
+ {-mpr->matrix_offset[2][2], 4, 2, false},
+ {+mpr->matrix_offset[2][2], 5, 2, true},
+ };
+ qsort(&axis_order, ARRAY_SIZE(axis_order), sizeof(axis_order[0]), BLI_sortutil_cmp_float);
+
+ const float scale_axis = 0.33f;
+ static const float axis_highlight[4] = {1, 1, 1, 1};
+ static const float axis_black[4] = {0, 0, 0, 1};
+ static float axis_color[3][4];
+ gpuPushMatrix();
+ gpuMultMatrix(mpr->matrix_offset);
+
+ bool draw_center_done = false;
+
+ for (int axis_index = 0; axis_index < ARRAY_SIZE(axis_order); axis_index++) {
+ const int index = axis_order[axis_index].index;
+ const int axis = axis_order[axis_index].axis;
+ const bool is_pos = axis_order[axis_index].is_pos;
+
+ /* Draw slightly before, so axis aligned arrows draw ontop. */
+ if ((draw_center_done == false) && (axis_order[axis_index].depth > -0.01f)) {
+
+ /* Circle defining active area (revert back to 2D space). */
+ {
+ gpuPopMatrix();
+ immUniformColor4fv(color);
+ imm_draw_circle_fill_3d(pos_id, 0, 0, 1.0f, DIAL_RESOLUTION);
+ gpuPushMatrix();
+ gpuMultMatrix(mpr->matrix_offset);
+ }
+
+ /* Center cube. */
+ {
+ float center[3], size[3];
+
+ zero_v3(center);
+ copy_v3_fl(size, HANDLE_SIZE);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+ glDepthFunc(GL_LEQUAL);
+ glBlendFunc(GL_ONE, GL_ZERO);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+ glLineWidth(1.0f);
+ immUniformColor4fv(axis_highlight);
+ imm_draw_cube_fill_3d(pos_id, center, size);
+ immUniformColor4fv(axis_black);
+ madd_v3_v3fl(
+ center,
+ (float [3]){
+ mpr->matrix_offset[0][2],
+ mpr->matrix_offset[1][2],
+ mpr->matrix_offset[2][2]},
+ 0.08f);
+ imm_draw_cube_wire_3d(pos_id, center, size);
+ glDisable(GL_BLEND);
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_DEPTH_TEST);
+ }
+
+ draw_center_done = true;
+ }
+ UI_GetThemeColor3fv(TH_AXIS_X + axis, axis_color[axis]);
+ axis_color[axis][3] = 1.0f;
+
+ const int index_z = axis;
+ const int index_y = (axis + 1) % 3;
+ const int index_x = (axis + 2) % 3;
+
+#define ROTATED_VERT(v_orig) \
+ { \
+ float v[3]; \
+ copy_v3_v3(v, v_orig); \
+ if (is_pos == 0) { \
+ v[2] *= -1.0f; \
+ } \
+ immVertex3f(pos_id, v[index_x] * scale_axis, v[index_y] * scale_axis, v[index_z] * scale_axis); \
+ } ((void)0)
+
+ bool ok = true;
+
+ /* skip view align axis */
+ if (len_squared_v2(mpr->matrix_offset[axis]) < 1e-6f && (mpr->matrix_offset[axis][2] > 0.0f) == is_pos) {
+ ok = false;
+ }
+ if (ok) {
+ immUniformColor4fv(index + 1 == mpr->highlight_part ? axis_highlight : axis_color[axis]);
+ immBegin(GWN_PRIM_TRI_FAN, 6);
+ ROTATED_VERT(cone_coords[4]);
+ for (int j = 0; j <= 4; j++) {
+ ROTATED_VERT(cone_coords[j % 4]);
+ }
+ immEnd();
+ }
+
+#undef ROTATED_VERT
+ }
+
+ gpuPopMatrix();
+ immUnbindProgram();
+}
+
+static void axis3d_draw_intern(
+ const bContext *UNUSED(C), wmManipulator *mpr,
+ const bool select, const bool highlight)
+{
+ const float *color = highlight ? mpr->color_hi : mpr->color;
+ float matrix_final[4][4];
+ float matrix_unit[4][4];
+
+ unit_m4(matrix_unit);
+
+ WM_manipulator_calc_matrix_final_params(
+ mpr,
+ &((struct WM_ManipulatorMatrixParams) {
+ .matrix_offset = matrix_unit,
+ }), matrix_final);
+
+ gpuPushMatrix();
+ gpuMultMatrix(matrix_final);
+
+ glEnable(GL_BLEND);
+ axis_geom_draw(mpr, color, select);
+ glDisable(GL_BLEND);
+ gpuPopMatrix();
+}
+
+static void manipulator_axis_draw(const bContext *C, wmManipulator *mpr)
+{
+ const bool is_modal = mpr->state & WM_MANIPULATOR_STATE_MODAL;
+ const bool is_highlight = (mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT) != 0 && (mpr->highlight_part == 0);
+
+ (void)is_modal;
+
+ glEnable(GL_BLEND);
+ axis3d_draw_intern(C, mpr, false, is_highlight);
+ glDisable(GL_BLEND);
+}
+
+static int manipulator_axis_test_select(
+ bContext *UNUSED(C), wmManipulator *mpr, const wmEvent *event)
+{
+ float point_local[2] = {UNPACK2(event->mval)};
+ sub_v2_v2(point_local, mpr->matrix_basis[3]);
+ mul_v2_fl(point_local, 1.0f / mpr->scale_basis);
+
+ const float len_sq = len_squared_v2(point_local);
+ if (len_sq > SQUARE(1.0 + HANDLE_SIZE)) {
+ return -1;
+ }
+
+ int part_best = -1;
+ int part_index = 1;
+ float i_best_len_sq = SQUARE(HANDLE_SIZE);
+ for (int i = 0; i < 3; i++) {
+ for (int is_pos = 0; is_pos < 2; is_pos++) {
+ float co[2] = {
+ mpr->matrix_offset[i][0] * (is_pos ? 1 : -1),
+ mpr->matrix_offset[i][1] * (is_pos ? 1 : -1),
+ };
+
+ bool ok = true;
+
+ /* Check if we're viewing on an axis, there is no point to clicking on the current axis so show the reverse. */
+ if (len_squared_v2(co) < 1e-6f && (mpr->matrix_offset[i][2] > 0.0f) == is_pos) {
+ ok = false;
+ }
+
+ if (ok) {
+ const float len_axis_sq = len_squared_v2v2(co, point_local);
+ if (len_axis_sq < i_best_len_sq) {
+ part_best = part_index;
+ i_best_len_sq = len_axis_sq;
+ }
+ }
+ part_index += 1;
+ }
+ }
+
+ if (part_best != -1) {
+ return part_best;
+ }
+
+ /* The 'mpr->scale_final' is already applied when projecting. */
+ if (len_sq < 1.0f) {
+ return 0;
+ }
+
+ return -1;
+}
+
+static int manipulator_axis_cursor_get(wmManipulator *mpr)
+{
+ if (mpr->highlight_part > 0) {
+ return BC_CROSSCURSOR;
+ }
+ return BC_NSEW_SCROLLCURSOR;
+}
+
+void VIEW3D_WT_navigate_rotate(wmManipulatorType *wt)
+{
+ /* identifiers */
+ wt->idname = "VIEW3D_WT_navigate_rotate";
+
+ /* api callbacks */
+ wt->draw = manipulator_axis_draw;
+ wt->test_select = manipulator_axis_test_select;
+ wt->cursor_get = manipulator_axis_cursor_get;
+
+ wt->struct_size = sizeof(wmManipulator);
+}
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 92ec93d8f20..e4747f733e5 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -817,8 +817,9 @@ typedef enum eGP_UserdefSettings {
} eGP_UserdefSettings;
enum {
- USER_MANIPULATOR_DRAW = (1 << 0),
- USER_MANIPULATOR_SHADED = (1 << 1),
+ USER_MANIPULATOR_DRAW = (1 << 0),
+ USER_MANIPULATOR_DRAW_NAVIGATE = (1 << 1),
+ USER_MANIPULATOR_SHADED = (1 << 8),
};
/* Color Picker Types.
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 273f9fcf280..bff6cdcf1bd 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -3525,6 +3525,11 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Manipulator", "Use 3D transform manipulator");
RNA_def_property_update(prop, 0, "rna_userdef_show_manipulator_update");
+ prop = RNA_def_property(srna, "show_manipulator_navigate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "manipulator_flag", USER_MANIPULATOR_DRAW_NAVIGATE);
+ RNA_def_property_ui_text(prop, "Navigate Manipulator", "Use 3D navigation manipulator");
+ RNA_def_property_update(prop, 0, "rna_userdef_show_manipulator_update");
+
/* TODO, expose once it's working. */
#if 0
prop = RNA_def_property(srna, "show_manipulator_shaded", PROP_BOOLEAN, PROP_NONE);