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:
-rw-r--r--source/blender/draw/CMakeLists.txt1
-rw-r--r--source/blender/draw/intern/draw_view.c13
-rw-r--r--source/blender/editors/include/ED_transform.h15
-rw-r--r--source/blender/editors/physics/physics_ops.c17
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c36
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c15
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c17
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c39
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h8
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c18
-rw-r--r--source/blender/editors/transform/transform.c29
-rw-r--r--source/blender/editors/transform/transform.h8
-rw-r--r--source/blender/editors/transform/transform_constraints.c2
-rw-r--r--source/blender/editors/transform/transform_generics.c1
-rw-r--r--source/blender/editors/transform/transform_manipulator.c1899
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c75
-rw-r--r--source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c6
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator.c70
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h2
19 files changed, 797 insertions, 1474 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index cf94fccd4e3..e921a65bfe8 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -43,6 +43,7 @@ set(INC
../editors/space_view3d
../render/extern/include
../render/intern/include
+ ../windowmanager
../../../intern/glew-mx
../../../intern/guardedalloc
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index eba72fac958..a0f0fb1a9ee 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -41,6 +41,9 @@
#include "UI_resources.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -699,5 +702,13 @@ void DRW_draw_manipulator(void)
const bContext *C = DRW_get_context();
View3D *v3d = CTX_wm_view3d(C);
v3d->zbuf = false;
- BIF_draw_manipulator(C);
+ ARegion *ar = CTX_wm_region(C);
+
+
+ /* TODO, only draws 3D manipulators right now, need to see how 2D drawing will work in new viewport */
+
+ /* 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, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
}
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 898eecd3e42..376ae8ca567 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -112,6 +112,8 @@ struct TransInfo;
struct BaseLegacy;
struct Scene;
struct Object;
+struct wmManipulatorGroup;
+struct wmManipulatorGroupType;
struct wmOperator;
/* UNUSED */
@@ -152,10 +154,17 @@ int BIF_countTransformOrientation(const struct bContext *C);
void Transform_Properties(struct wmOperatorType *ot, int flags);
-/* view3d manipulators */
+/* transform manipulators */
+
+void TRANSFORM_WGT_manipulator(struct wmManipulatorGroupType *wgt);
+
+void TRANSFORM_WGT_object(struct wmManipulatorGroupType *wgt);
+
+bool WIDGETGROUP_manipulator2d_poll(const struct bContext *C, struct wmManipulatorGroupType *wgrouptype);
+void WIDGETGROUP_manipulator2d_init(const struct bContext *C, struct wmManipulatorGroup *wgroup);
+void WIDGETGROUP_manipulator2d_refresh(const struct bContext *C, struct wmManipulatorGroup *wgroup);
+void WIDGETGROUP_manipulator2d_draw_prepare(const struct bContext *C, struct wmManipulatorGroup *wgroup);
-int BIF_do_manipulator(struct bContext *C, const struct wmEvent *event, struct wmOperator *op);
-void BIF_draw_manipulator(const struct bContext *C);
/* Snapping */
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index b1d708ebc07..758ef43590e 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -137,23 +137,6 @@ static void keymap_particle(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
- /* Shift+LMB behavior first, so it has priority over KM_ANY item below. */
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", true);
- RNA_boolean_set(kmi->ptr, "use_accurate", false);
-
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
- RNA_boolean_set(kmi->ptr, "use_accurate", true);
-
- /* Using KM_ANY here to allow holding modifiers before starting to transform. */
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
- RNA_boolean_set(kmi->ptr, "use_accurate", false);
-
WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 62bcb771226..af25c9de781 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -54,6 +54,7 @@
#include "ED_space_api.h"
#include "ED_screen.h"
+#include "ED_transform.h"
#include "GPU_compositing.h"
#include "GPU_framebuffer.h"
@@ -341,7 +342,7 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->near = 0.01f;
v3d->far = 1000.0f;
- v3d->twflag |= U.tw_flag & V3D_USE_MANIPULATOR;
+ v3d->twflag |= U.manipulator_flag & V3D_USE_MANIPULATOR;
v3d->twtype = V3D_MANIP_TRANSLATE;
v3d->around = V3D_AROUND_CENTER_MEAN;
@@ -488,6 +489,13 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
ListBase *lb;
wmKeyMap *keymap;
+ if (!ar->manipulator_map) {
+ ar->manipulator_map = WM_manipulatormap_new_from_type(&(const struct wmManipulatorMapType_Params) {
+ "View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW});
+ }
+
+ WM_manipulatormap_add_handlers(ar, ar->manipulator_map);
+
/* object ops. */
/* important to be before Pose keymap since they can both be enabled at once */
@@ -719,6 +727,16 @@ static void view3d_dropboxes(void)
WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
}
+static void view3d_widgets(void)
+{
+ const struct wmManipulatorMapType_Params wmap_params = {
+ .idname = "View3D",
+ .spaceid = SPACE_VIEW3D, .regionid = RGN_TYPE_WINDOW,
+ };
+ wmManipulatorMapType *wmaptype = WM_manipulatormaptype_ensure(&wmap_params);
+
+ WM_manipulatorgrouptype_append(wmaptype, TRANSFORM_WGT_manipulator);
+}
/* type callback, not region itself */
@@ -815,7 +833,9 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
{
Scene *scene = sc->scene;
View3D *v3d = sa->spacedata.first;
-
+ RegionView3D *rv3d = ar->regiondata;
+ wmManipulatorMap *mmap = ar->manipulator_map;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -841,6 +861,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
if (wmn->reference)
view3d_recalc_used_layers(ar, wmn, wmn->reference);
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
case ND_FRAME:
case ND_TRANSFORM:
@@ -852,6 +873,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_MARKERS:
case ND_MODE:
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
case ND_WORLD:
/* handled by space_view3d_listener() for v3d access */
@@ -859,7 +881,6 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_DRAW_RENDER_VIEWPORT:
{
if (v3d->camera && (scene == wmn->reference)) {
- RegionView3D *rv3d = ar->regiondata;
if (rv3d->persp == RV3D_CAMOB) {
ED_region_tag_redraw(ar);
}
@@ -884,6 +905,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_POINTCACHE:
case ND_LOD:
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
}
switch (wmn->action) {
@@ -896,6 +918,8 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
switch (wmn->data) {
case ND_SELECT:
{
+ WM_manipulatormap_tag_refresh(mmap);
+
if (scene->obedit) {
Object *ob = scene->obedit;
if (ob->type == OB_MESH) {
@@ -920,7 +944,6 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_DRAW_RENDER_VIEWPORT:
{
if (v3d->camera && (v3d->camera->data == wmn->reference)) {
- RegionView3D *rv3d = ar->regiondata;
if (rv3d->persp == RV3D_CAMOB) {
ED_region_tag_redraw(ar);
}
@@ -979,6 +1002,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
break;
case ND_LIGHTING_DRAW:
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
}
break;
@@ -998,10 +1022,10 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case NC_SPACE:
if (wmn->data == ND_SPACE_VIEW3D) {
if (wmn->subtype == NS_VIEW3D_GPU) {
- RegionView3D *rv3d = ar->regiondata;
rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
}
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
}
break;
case NC_ID:
@@ -1023,6 +1047,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
bScreen *sc_ref = wmn->reference;
view3d_recalc_used_layers(ar, wmn, sc_ref->scene);
}
+ WM_manipulatormap_tag_refresh(mmap);
ED_region_tag_redraw(ar);
break;
}
@@ -1393,6 +1418,7 @@ void ED_spacetype_view3d(void)
st->operatortypes = view3d_operatortypes;
st->keymap = view3d_keymap;
st->dropboxes = view3d_dropboxes;
+ st->manipulators = view3d_widgets;
st->context = view3d_context;
st->id_remap = view3d_id_remap;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index e98cff85d0d..a3bdc09143f 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -84,6 +84,7 @@
#include "RE_engine.h"
#include "WM_api.h"
+#include "WM_types.h"
#include "view3d_intern.h" /* own include */
@@ -2211,12 +2212,18 @@ static void view3d_draw_reference_images(const bContext *UNUSED(C))
/**
* 3D manipulators
-*/
-static void view3d_draw_manipulator(const bContext *C)
+ */
+static void view3d_draw_manipulators(const bContext *C, const ARegion *ar)
{
View3D *v3d = CTX_wm_view3d(C);
v3d->zbuf = false;
- BIF_draw_manipulator(C);
+
+ /* TODO, only draws 3D manipulators right now, need to see how 2D drawing will work in new viewport */
+
+ /* 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, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
}
/**
@@ -2309,7 +2316,7 @@ static void view3d_draw_view(const bContext *C, ARegion *ar, DrawData *draw_data
view3d_draw_other_elements(C, ar);
view3d_draw_tool_ui(C);
view3d_draw_reference_images(C);
- view3d_draw_manipulator(C);
+ view3d_draw_manipulators(C, ar);
gpuMatrixEnd();
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index 7070cadb414..14b8f78e4c7 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -79,6 +79,7 @@
#include "BIF_glutil.h"
#include "WM_api.h"
+#include "WM_types.h"
#include "BLF_api.h"
#include "BLT_translation.h"
@@ -1709,10 +1710,6 @@ static void view3d_draw_objects(
view3d_draw_bgpic_test(scene, ar, v3d, true, do_camera_frame);
}
- if (!draw_offscreen) {
- BIF_draw_manipulator(C);
- }
-
/* cleanup */
if (v3d->zbuf) {
v3d->zbuf = false;
@@ -2429,6 +2426,11 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Sce
/* main drawing call */
view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
+ /* 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, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
+
/* post process */
if (do_compositing) {
GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);
@@ -2553,6 +2555,13 @@ void view3d_main_region_draw_legacy(const bContext *C, ARegion *ar)
if (v3d->drawtype == OB_RENDER)
view3d_main_region_draw_engine(C, scene, ar, v3d, clip_border, &border_rect);
+ VP_legacy_view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D);
+
+ ED_region_pixelspace(ar);
+
view3d_main_region_draw_info(C, scene, ar, v3d, grid_unit, render_border);
glMatrixMode(GL_PROJECTION);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 46592194035..804336b2976 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -4746,45 +4746,6 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
/* ***************** manipulator op ******************* */
-
-static int manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- View3D *v3d = CTX_wm_view3d(C);
-
- if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
- if (!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
-
- /* note; otherwise opengl won't work */
- view3d_operator_needs_opengl(C);
-
- if (BIF_do_manipulator(C, event, op) == 0)
- return OPERATOR_PASS_THROUGH;
-
- return OPERATOR_FINISHED;
-}
-
-void VIEW3D_OT_manipulator(wmOperatorType *ot)
-{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "3D Manipulator";
- ot->description = "Manipulate selected item by axis";
- ot->idname = "VIEW3D_OT_manipulator";
-
- /* api callbacks */
- ot->invoke = manipulator_invoke;
-
- ot->poll = ED_operator_view3d_active;
-
- /* properties to pass to transform */
- Transform_Properties(ot, P_CONSTRAINT);
-
- prop = RNA_def_boolean(ot->srna, "use_planar_constraint", false, "Planar Constraint", "Limit the transformation to the "
- "two axes that have not been clicked (translate/scale only)");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
-}
-
static int enable_manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index db16f95d69b..721215a1281 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -51,6 +51,7 @@ struct SceneLayer;
struct wmOperatorType;
struct wmWindowManager;
struct wmKeyConfig;
+struct wmManipulatorGroupType;
/* drawing flags: */
enum {
@@ -101,7 +102,6 @@ void VIEW3D_OT_view_orbit(struct wmOperatorType *ot);
void VIEW3D_OT_view_roll(struct wmOperatorType *ot);
void VIEW3D_OT_clip_border(struct wmOperatorType *ot);
void VIEW3D_OT_cursor3d(struct wmOperatorType *ot);
-void VIEW3D_OT_manipulator(struct wmOperatorType *ot);
void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot);
void VIEW3D_OT_render_border(struct wmOperatorType *ot);
void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot);
@@ -313,6 +313,12 @@ ARegion *view3d_has_tools_region(ScrArea *sa);
extern const char *view3d_context_dir[]; /* doc access */
+/* view3d_widgets.c */
+void VIEW3D_WGT_lamp (struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_camera (struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_force_field (struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_armature_facemaps(struct wmManipulatorGroupType *wgt);
+
/* draw_volume.c */
void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
const float min[3], const float max[3],
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index d71639c35d2..e14a0c63ee4 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -193,7 +193,6 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_render_border);
WM_operatortype_append(VIEW3D_OT_clear_render_border);
WM_operatortype_append(VIEW3D_OT_zoom_border);
- WM_operatortype_append(VIEW3D_OT_manipulator);
WM_operatortype_append(VIEW3D_OT_enable_manipulator);
WM_operatortype_append(VIEW3D_OT_cursor3d);
WM_operatortype_append(VIEW3D_OT_select_lasso);
@@ -240,23 +239,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
/* only for region 3D window */
keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0);
- /* Shift+LMB behavior first, so it has priority over KM_ANY item below. */
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", true);
- RNA_boolean_set(kmi->ptr, "use_accurate", false);
-
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
- RNA_boolean_set(kmi->ptr, "use_accurate", true);
-
- /* Using KM_ANY here to allow holding modifiers before starting to transform. */
- kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
- RNA_boolean_set(kmi->ptr, "release_confirm", true);
- RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
- RNA_boolean_set(kmi->ptr, "use_accurate", false);
-
WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_rotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index ead3817bae4..1be4d0c3172 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1702,7 +1702,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
{
TransInfo *t = (TransInfo *)customdata;
- if (t->helpline != HLP_NONE && !(t->flag & T_USES_MANIPULATOR)) {
+ if (t->helpline != HLP_NONE) {
float vecrot[3], cent[2];
float mval[3] = { x, y, 0.0f };
@@ -3423,7 +3423,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3])
constraintTransLim(t, td);
}
-static void applyResize(TransInfo *t, const int mval[2])
+static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td;
float mat[3][3];
@@ -3434,15 +3434,7 @@ static void applyResize(TransInfo *t, const int mval[2])
copy_v3_v3(t->values, t->auto_values);
}
else {
- float ratio;
-
- /* for manipulator, center handle, the scaling can't be done relative to center */
- if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
- ratio = 1.0f - ((t->mouse.imval[0] - mval[0]) + (t->mouse.imval[1] - mval[1])) / 100.0f;
- }
- else {
- ratio = t->values[0];
- }
+ float ratio = t->values[0];
copy_v3_fl(t->values, ratio);
@@ -5266,23 +5258,14 @@ static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3])
td->loc[1] = oldy;
}
-static void applyBoneSize(TransInfo *t, const int mval[2])
+static void applyBoneSize(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td = t->data;
float size[3], mat[3][3];
- float ratio;
+ float ratio = t->values[0];
int i;
char str[UI_MAX_DRAW_STR];
-
- // TRANSFORM_FIX_ME MOVE TO MOUSE INPUT
- /* for manipulator, center handle, the scaling can't be done relative to center */
- if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
- ratio = 1.0f - ((t->mouse.imval[0] - mval[0]) + (t->mouse.imval[1] - mval[1])) / 100.0f;
- }
- else {
- ratio = t->values[0];
- }
-
+
copy_v3_fl(size, ratio);
snapGridIncrement(t, size);
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 774f5ad6790..8765169fcb2 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -498,8 +498,7 @@ typedef struct TransInfo {
#define T_CAMERA (1 << 4)
// trans on points, having no rotation/scale
#define T_POINTS (1 << 6)
- // for manipulator exceptions, like scaling using center point, drawing help lines
-#define T_USES_MANIPULATOR (1 << 7)
+/* empty slot - (1 << 7) */
/* restrictions flags */
#define T_ALL_RESTRICTIONS ((1 << 8)|(1 << 9)|(1 << 10))
@@ -636,7 +635,10 @@ void flushTransMasking(TransInfo *t);
void flushTransPaintCurve(TransInfo *t);
void restoreBones(TransInfo *t);
-/*********************** exported from transform_manipulator.c ********** */
+/*********************** transform_manipulator.c ********** */
+
+#define MANIPULATOR_AXIS_LINE_WIDTH 2.0
+
bool gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */
/*********************** TransData Creation and General Handling *********** */
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index d9c0942dece..cd724370e17 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -706,8 +706,6 @@ void drawConstraint(TransInfo *t)
return;
if (!(tc->mode & CON_APPLY))
return;
- if (t->flag & T_USES_MANIPULATOR)
- return;
if (t->flag & T_NO_CONSTRAINT)
return;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 1cf53f95ef1..3e427d2973b 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1228,7 +1228,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->animtimer = (animscreen) ? animscreen->animtimer : NULL;
/* turn manipulator off during transform */
- // FIXME: but don't do this when USING the manipulator...
if (t->flag & T_MODAL) {
t->twtype = v3d->twtype;
v3d->twtype = 0;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 624cd7db679..91aaa5da0e9 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -39,6 +39,7 @@
#include "DNA_curve_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_lattice_types.h"
+#include "DNA_manipulator_types.h"
#include "DNA_meta_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
@@ -67,15 +68,19 @@
#include "ED_armature.h"
#include "ED_curve.h"
+#include "ED_object.h"
#include "ED_particle.h"
#include "ED_view3d.h"
#include "ED_gpencil.h"
+#include "ED_screen.h"
#include "UI_resources.h"
/* local module include */
#include "transform.h"
+#include "MEM_guardedalloc.h"
+
#include "GPU_select.h"
#include "GPU_immediate.h"
#include "GPU_matrix.h"
@@ -90,25 +95,350 @@
#define MAN_ROT_X (1 << 3)
#define MAN_ROT_Y (1 << 4)
#define MAN_ROT_Z (1 << 5)
-#define MAN_ROT_V (1 << 6)
-#define MAN_ROT_T (1 << 7)
-#define MAN_ROT_C (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z | MAN_ROT_V | MAN_ROT_T)
+#define MAN_ROT_C (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z)
#define MAN_SCALE_X (1 << 8)
#define MAN_SCALE_Y (1 << 9)
#define MAN_SCALE_Z (1 << 10)
#define MAN_SCALE_C (MAN_SCALE_X | MAN_SCALE_Y | MAN_SCALE_Z)
-/* color codes */
-
-#define MAN_RGB 0
-#define MAN_GHOST 1
-#define MAN_MOVECOL 2
-
/* threshold for testing view aligned manipulator axis */
#define TW_AXIS_DOT_MIN 0.02f
#define TW_AXIS_DOT_MAX 0.1f
+/* axes as index */
+enum {
+ MAN_AXIS_TRANS_X = 0,
+ MAN_AXIS_TRANS_Y,
+ MAN_AXIS_TRANS_Z,
+ MAN_AXIS_TRANS_C,
+
+ MAN_AXIS_ROT_X,
+ MAN_AXIS_ROT_Y,
+ MAN_AXIS_ROT_Z,
+ MAN_AXIS_ROT_C,
+ MAN_AXIS_ROT_T, /* trackball rotation */
+
+ MAN_AXIS_SCALE_X,
+ MAN_AXIS_SCALE_Y,
+ MAN_AXIS_SCALE_Z,
+ MAN_AXIS_SCALE_C,
+
+ /* special */
+ MAN_AXIS_TRANS_XY,
+ MAN_AXIS_TRANS_YZ,
+ MAN_AXIS_TRANS_ZX,
+
+ MAN_AXIS_SCALE_XY,
+ MAN_AXIS_SCALE_YZ,
+ MAN_AXIS_SCALE_ZX,
+
+ MAN_AXIS_LAST,
+};
+
+/* axis types */
+enum {
+ MAN_AXES_ALL = 0,
+ MAN_AXES_TRANSLATE,
+ MAN_AXES_ROTATE,
+ MAN_AXES_SCALE,
+};
+
+typedef struct ManipulatorGroup {
+ bool all_hidden;
+
+ struct wmManipulator *translate_x,
+ *translate_y,
+ *translate_z,
+ *translate_xy,
+ *translate_yz,
+ *translate_zx,
+ *translate_c,
+
+ *rotate_x,
+ *rotate_y,
+ *rotate_z,
+ *rotate_c,
+ *rotate_t, /* trackball rotation */
+
+ *scale_x,
+ *scale_y,
+ *scale_z,
+ *scale_xy,
+ *scale_yz,
+ *scale_zx,
+ *scale_c;
+} ManipulatorGroup;
+
+
+/* **************** Utilities **************** */
+
+/* loop over axes */
+#define MAN_ITER_AXES_BEGIN(axis, axis_idx) \
+ { \
+ wmManipulator *axis; \
+ int axis_idx; \
+ for (axis_idx = 0; axis_idx < MAN_AXIS_LAST; axis_idx++) { \
+ axis = manipulator_get_axis_from_index(man, axis_idx);
+
+#define MAN_ITER_AXES_END \
+ } \
+ } ((void)0)
+
+static wmManipulator *manipulator_get_axis_from_index(const ManipulatorGroup *man, const short axis_idx)
+{
+ BLI_assert(IN_RANGE_INCL(axis_idx, (float)MAN_AXIS_TRANS_X, (float)MAN_AXIS_LAST));
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ return man->translate_x;
+ case MAN_AXIS_TRANS_Y:
+ return man->translate_y;
+ case MAN_AXIS_TRANS_Z:
+ return man->translate_z;
+ case MAN_AXIS_TRANS_XY:
+ return man->translate_xy;
+ case MAN_AXIS_TRANS_YZ:
+ return man->translate_yz;
+ case MAN_AXIS_TRANS_ZX:
+ return man->translate_zx;
+ case MAN_AXIS_TRANS_C:
+ return man->translate_c;
+ case MAN_AXIS_ROT_X:
+ return man->rotate_x;
+ case MAN_AXIS_ROT_Y:
+ return man->rotate_y;
+ case MAN_AXIS_ROT_Z:
+ return man->rotate_z;
+ case MAN_AXIS_ROT_C:
+ return man->rotate_c;
+ case MAN_AXIS_ROT_T:
+ return man->rotate_t;
+ case MAN_AXIS_SCALE_X:
+ return man->scale_x;
+ case MAN_AXIS_SCALE_Y:
+ return man->scale_y;
+ case MAN_AXIS_SCALE_Z:
+ return man->scale_z;
+ case MAN_AXIS_SCALE_XY:
+ return man->scale_xy;
+ case MAN_AXIS_SCALE_YZ:
+ return man->scale_yz;
+ case MAN_AXIS_SCALE_ZX:
+ return man->scale_zx;
+ case MAN_AXIS_SCALE_C:
+ return man->scale_c;
+ }
+
+ return NULL;
+}
+
+static short manipulator_get_axis_type(const ManipulatorGroup *man, const wmManipulator *axis)
+{
+ if (ELEM(axis, man->translate_x, man->translate_y, man->translate_z, man->translate_c,
+ man->translate_xy, man->translate_yz, man->translate_zx))
+ {
+ return MAN_AXES_TRANSLATE;
+ }
+ else if (ELEM(axis, man->rotate_x, man->rotate_y, man->rotate_z, man->rotate_c, man->rotate_t)) {
+ return MAN_AXES_ROTATE;
+ }
+ else {
+ return MAN_AXES_SCALE;
+ }
+}
+
+/* get index within axis type, so that x == 0, y == 1 and z == 2, no matter which axis type */
+static unsigned int manipulator_index_normalize(const int axis_idx)
+{
+ if (axis_idx > MAN_AXIS_TRANS_ZX) {
+ return axis_idx - 16;
+ }
+ else if (axis_idx > MAN_AXIS_SCALE_C) {
+ return axis_idx - 13;
+ }
+ else if (axis_idx > MAN_AXIS_ROT_T) {
+ return axis_idx - 9;
+ }
+ else if (axis_idx > MAN_AXIS_TRANS_C) {
+ return axis_idx - 4;
+ }
+
+ return axis_idx;
+}
+
+static bool manipulator_is_axis_visible(
+ const View3D *v3d, const RegionView3D *rv3d,
+ const float idot[3], const int axis_type, const int axis_idx)
+{
+ const unsigned int aidx_norm = manipulator_index_normalize(axis_idx);
+ /* don't draw axis perpendicular to the view */
+ if (aidx_norm < 3 && idot[aidx_norm] < TW_AXIS_DOT_MIN) {
+ return false;
+ }
+
+ if ((axis_type == MAN_AXES_TRANSLATE && !(v3d->twtype & V3D_MANIP_TRANSLATE)) ||
+ (axis_type == MAN_AXES_ROTATE && !(v3d->twtype & V3D_MANIP_ROTATE)) ||
+ (axis_type == MAN_AXES_SCALE && !(v3d->twtype & V3D_MANIP_SCALE)))
+ {
+ return false;
+ }
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ return (rv3d->twdrawflag & MAN_TRANS_X);
+ case MAN_AXIS_TRANS_Y:
+ return (rv3d->twdrawflag & MAN_TRANS_Y);
+ case MAN_AXIS_TRANS_Z:
+ return (rv3d->twdrawflag & MAN_TRANS_Z);
+ case MAN_AXIS_TRANS_C:
+ return (rv3d->twdrawflag & MAN_TRANS_C);
+ case MAN_AXIS_ROT_X:
+ return (rv3d->twdrawflag & MAN_ROT_X);
+ case MAN_AXIS_ROT_Y:
+ return (rv3d->twdrawflag & MAN_ROT_Y);
+ case MAN_AXIS_ROT_Z:
+ return (rv3d->twdrawflag & MAN_ROT_Z);
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_ROT_T:
+ return (rv3d->twdrawflag & MAN_ROT_C);
+ case MAN_AXIS_SCALE_X:
+ return (rv3d->twdrawflag & MAN_SCALE_X);
+ case MAN_AXIS_SCALE_Y:
+ return (rv3d->twdrawflag & MAN_SCALE_Y);
+ case MAN_AXIS_SCALE_Z:
+ return (rv3d->twdrawflag & MAN_SCALE_Z);
+ case MAN_AXIS_SCALE_C:
+ return (rv3d->twdrawflag & MAN_SCALE_C && (v3d->twtype & V3D_MANIP_TRANSLATE) == 0);
+ case MAN_AXIS_TRANS_XY:
+ return (rv3d->twdrawflag & MAN_TRANS_X &&
+ rv3d->twdrawflag & MAN_TRANS_Y &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ case MAN_AXIS_TRANS_YZ:
+ return (rv3d->twdrawflag & MAN_TRANS_Y &&
+ rv3d->twdrawflag & MAN_TRANS_Z &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ case MAN_AXIS_TRANS_ZX:
+ return (rv3d->twdrawflag & MAN_TRANS_Z &&
+ rv3d->twdrawflag & MAN_TRANS_X &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ case MAN_AXIS_SCALE_XY:
+ return (rv3d->twdrawflag & MAN_SCALE_X &&
+ rv3d->twdrawflag & MAN_SCALE_Y &&
+ (v3d->twtype & V3D_MANIP_TRANSLATE) == 0 &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ case MAN_AXIS_SCALE_YZ:
+ return (rv3d->twdrawflag & MAN_SCALE_Y &&
+ rv3d->twdrawflag & MAN_SCALE_Z &&
+ (v3d->twtype & V3D_MANIP_TRANSLATE) == 0 &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ case MAN_AXIS_SCALE_ZX:
+ return (rv3d->twdrawflag & MAN_SCALE_Z &&
+ rv3d->twdrawflag & MAN_SCALE_X &&
+ (v3d->twtype & V3D_MANIP_TRANSLATE) == 0 &&
+ (v3d->twtype & V3D_MANIP_ROTATE) == 0);
+ }
+ return false;
+}
+
+static void manipulator_get_axis_color(
+ const int axis_idx, const float idot[3],
+ float r_col[4], float r_col_hi[4])
+{
+ /* alpha values for normal/highlighted states */
+ const float alpha = 0.6f;
+ const float alpha_hi = 1.0f;
+ float alpha_fac;
+
+ const int axis_idx_norm = manipulator_index_normalize(axis_idx);
+ /* get alpha fac based on axis angle, to fade axis out when hiding it because it points towards view */
+ if (axis_idx_norm < 3) {
+ const float idot_axis = idot[axis_idx_norm];
+ alpha_fac = (idot_axis > TW_AXIS_DOT_MAX) ?
+ 1.0f : (idot_axis < TW_AXIS_DOT_MIN) ?
+ 0.0f : ((idot_axis - TW_AXIS_DOT_MIN) / (TW_AXIS_DOT_MAX - TW_AXIS_DOT_MIN));
+ }
+ else {
+ /* trackball rotation axis is a special case, we only draw a slight overlay */
+ alpha_fac = (axis_idx == MAN_AXIS_ROT_T) ? 0.1f : 1.0f;
+ }
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_SCALE_X:
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_SCALE_XY:
+ UI_GetThemeColor4fv(TH_AXIS_X, r_col);
+ break;
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_SCALE_Y:
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_SCALE_YZ:
+ UI_GetThemeColor4fv(TH_AXIS_Y, r_col);
+ break;
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_ROT_Z:
+ case MAN_AXIS_SCALE_Z:
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_ZX:
+ UI_GetThemeColor4fv(TH_AXIS_Z, r_col);
+ break;
+ case MAN_AXIS_TRANS_C:
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_SCALE_C:
+ case MAN_AXIS_ROT_T:
+ copy_v4_fl(r_col, 1.0f);
+ break;
+ }
+
+ copy_v4_v4(r_col_hi, r_col);
+
+ r_col[3] = alpha * alpha_fac;
+ r_col_hi[3] = alpha_hi * alpha_fac;
+}
+
+static void manipulator_get_axis_constraint(const int axis_idx, int r_axis[3])
+{
+ zero_v3_int(r_axis);
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_SCALE_X:
+ r_axis[0] = 1;
+ break;
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_SCALE_Y:
+ r_axis[1] = 1;
+ break;
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_ROT_Z:
+ case MAN_AXIS_SCALE_Z:
+ r_axis[2] = 1;
+ break;
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_SCALE_XY:
+ r_axis[0] = r_axis[1] = 1;
+ break;
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_SCALE_YZ:
+ r_axis[1] = r_axis[2] = 1;
+ break;
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_ZX:
+ r_axis[2] = r_axis[0] = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+
+/* **************** Preparation Stuff **************** */
+
/* transform widget center calc helper for below */
static void calc_tw_center(Scene *scene, const float co[3])
{
@@ -591,7 +921,6 @@ static int calc_manipulator_stats(const bContext *C)
if (ob == NULL)
ob = base->object;
calc_tw_center(scene, base->object->obmat[3]);
- protectflag_to_drawflags(base->object->protectflag, &rv3d->twdrawflag);
totsel++;
}
}
@@ -671,1387 +1000,389 @@ static int calc_manipulator_stats(const bContext *C)
return totsel;
}
-/* don't draw axis perpendicular to the view */
-static void test_manipulator_axis(const bContext *C)
+static void manipulator_get_idot(RegionView3D *rv3d, float r_idot[3])
{
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
float view_vec[3], axis_vec[3];
- float idot;
- int i;
-
- const int twdrawflag_axis[3] = {
- (MAN_TRANS_X | MAN_SCALE_X),
- (MAN_TRANS_Y | MAN_SCALE_Y),
- (MAN_TRANS_Z | MAN_SCALE_Z)};
-
ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], view_vec);
-
- for (i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
normalize_v3_v3(axis_vec, rv3d->twmat[i]);
- rv3d->tw_idot[i] = idot = 1.0f - fabsf(dot_v3v3(view_vec, axis_vec));
- if (idot < TW_AXIS_DOT_MIN) {
- rv3d->twdrawflag &= ~twdrawflag_axis[i];
- }
- }
-}
-
-
-/* ******************** DRAWING STUFFIES *********** */
-
-static float screen_aligned(RegionView3D *rv3d, float mat[4][4])
-{
- gpuTranslate3fv(mat[3]);
-
- /* sets view screen aligned */
- gpuRotate3f(-360.0f * saacos(rv3d->viewquat[0]) / (float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]);
-
- return len_v3(mat[0]); /* draw scale */
-}
-
-
-/* radring = radius of doughnut rings
- * radhole = radius hole
- * start = starting segment (based on nrings)
- * end = end segment
- * nsides = amount of points in ring
- * nrigns = amount of rings
- */
-static void partial_doughnut(unsigned int pos, float radring, float radhole, int start, int end, int nsides, int nrings)
-{
- float theta, phi, theta1;
- float cos_theta, sin_theta;
- float cos_theta1, sin_theta1;
- float ring_delta, side_delta;
- int i, j, do_caps = true;
-
- if (start == 0 && end == nrings) do_caps = false;
-
- ring_delta = 2.0f * (float)M_PI / (float)nrings;
- side_delta = 2.0f * (float)M_PI / (float)nsides;
-
- theta = (float)M_PI + 0.5f * ring_delta;
- cos_theta = cosf(theta);
- sin_theta = sinf(theta);
-
- for (i = nrings - 1; i >= 0; i--) {
- theta1 = theta + ring_delta;
- cos_theta1 = cosf(theta1);
- sin_theta1 = sinf(theta1);
-
- if (do_caps && i == start) { // cap
- immBegin(GL_TRIANGLE_FAN, nsides+1);
- phi = 0.0;
- for (j = nsides; j >= 0; j--) {
- float cos_phi, sin_phi, dist;
-
- phi += side_delta;
- cos_phi = cosf(phi);
- sin_phi = sinf(phi);
- dist = radhole + radring * cos_phi;
-
- immVertex3f(pos, cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi);
- }
- immEnd();
- }
- if (i >= start && i <= end) {
- immBegin(GL_TRIANGLE_STRIP, (nsides+1) * 2);
- phi = 0.0;
- for (j = nsides; j >= 0; j--) {
- float cos_phi, sin_phi, dist;
-
- phi += side_delta;
- cos_phi = cosf(phi);
- sin_phi = sinf(phi);
- dist = radhole + radring * cos_phi;
-
- immVertex3f(pos, cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi);
- immVertex3f(pos, cos_theta * dist, -sin_theta * dist, radring * sin_phi);
- }
- immEnd();
- }
-
- if (do_caps && i == end) { // cap
- immBegin(GL_TRIANGLE_FAN, nsides+1);
- phi = 0.0;
- for (j = nsides; j >= 0; j--) {
- float cos_phi, sin_phi, dist;
-
- phi -= side_delta;
- cos_phi = cosf(phi);
- sin_phi = sinf(phi);
- dist = radhole + radring * cos_phi;
-
- immVertex3f(pos, cos_theta * dist, -sin_theta * dist, radring * sin_phi);
- }
- immEnd();
- }
-
-
- theta = theta1;
- cos_theta = cos_theta1;
- sin_theta = sin_theta1;
+ r_idot[i] = 1.0f - fabsf(dot_v3v3(view_vec, axis_vec));
}
}
-static char axisBlendAngle(float idot)
+static void manipulator_prepare_mat(const bContext *C, View3D *v3d, RegionView3D *rv3d)
{
- if (idot > TW_AXIS_DOT_MAX) {
- return 255;
- }
- else if (idot < TW_AXIS_DOT_MIN) {
- return 0;
- }
- else {
- return (char)(255.0f * (idot - TW_AXIS_DOT_MIN) / (TW_AXIS_DOT_MAX - TW_AXIS_DOT_MIN));
- }
-}
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
-/* three colors can be set:
- * gray for ghosting
- * moving: in transform theme color
- * else the red/green/blue
- */
-static void manipulator_setcolor(View3D *v3d, char axis, int colcode, unsigned char alpha)
-{
- unsigned char col[4] = {0};
- col[3] = alpha;
+ switch (v3d->around) {
+ case V3D_AROUND_CENTER_BOUNDS:
+ case V3D_AROUND_ACTIVE:
+ {
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ Object *ob = OBACT_NEW;
- if (colcode == MAN_GHOST) {
- col[3] = 70;
- }
- else if (colcode == MAN_MOVECOL) {
- UI_GetThemeColor3ubv(TH_TRANSFORM, col);
- }
- else {
- switch (axis) {
- case 'C':
- UI_GetThemeColor3ubv(TH_TRANSFORM, col);
- if (v3d->twmode == V3D_MANIP_LOCAL) {
- col[0] = col[0] > 200 ? 255 : col[0] + 55;
- col[1] = col[1] > 200 ? 255 : col[1] + 55;
- col[2] = col[2] > 200 ? 255 : col[2] + 55;
+ if (((v3d->around == V3D_AROUND_ACTIVE) && (scene->obedit == NULL)) &&
+ ((gpd == NULL) || !(gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
+ (!(ob->mode & OB_MODE_POSE)))
+ {
+ copy_v3_v3(rv3d->twmat[3], ob->obmat[3]);
}
- else if (v3d->twmode == V3D_MANIP_NORMAL) {
- col[0] = col[0] < 55 ? 0 : col[0] - 55;
- col[1] = col[1] < 55 ? 0 : col[1] - 55;
- col[2] = col[2] < 55 ? 0 : col[2] - 55;
+ else {
+ mid_v3_v3v3(rv3d->twmat[3], scene->twmin, scene->twmax);
}
break;
- case 'X':
- UI_GetThemeColor3ubv(TH_AXIS_X, col);
- break;
- case 'Y':
- UI_GetThemeColor3ubv(TH_AXIS_Y, col);
- break;
- case 'Z':
- UI_GetThemeColor3ubv(TH_AXIS_Z, col);
- break;
- default:
- BLI_assert(0);
- break;
}
+ case V3D_AROUND_LOCAL_ORIGINS:
+ case V3D_AROUND_CENTER_MEAN:
+ copy_v3_v3(rv3d->twmat[3], scene->twcent);
+ break;
+ case V3D_AROUND_CURSOR:
+ copy_v3_v3(rv3d->twmat[3], ED_view3d_cursor3d_get(scene, v3d));
+ break;
}
-
- immUniformColor4ubv(col);
}
-static void manipulator_axis_order(RegionView3D *rv3d, int r_axis_order[3])
+/**
+ * Sets up \a r_start and \a r_len to define arrow line range.
+ * Needed to adjust line drawing for combined manipulator axis types.
+ */
+static void manipulator_line_range(const View3D *v3d, const short axis_type, float *r_start, float *r_len)
{
- float axis_values[3];
- float vec[3];
+ const float ofs = 0.2f;
- ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], vec);
+ *r_start = 0.2f;
+ *r_len = 1.0f;
- axis_values[0] = -dot_v3v3(rv3d->twmat[0], vec);
- axis_values[1] = -dot_v3v3(rv3d->twmat[1], vec);
- axis_values[2] = -dot_v3v3(rv3d->twmat[2], vec);
-
- axis_sort_v3(axis_values, r_axis_order);
-}
-
-/* viewmatrix should have been set OK, also no shademode! */
-static void draw_manipulator_axes_single(View3D *v3d, RegionView3D *rv3d, int colcode,
- int flagx, int flagy, int flagz, int axis,
- const bool is_picksel, unsigned int pos)
-{
- switch (axis) {
- case 0:
- /* axes */
- if (flagx) {
- if (is_picksel) {
- if (flagx & MAN_SCALE_X) GPU_select_load_id(MAN_SCALE_X);
- else if (flagx & MAN_TRANS_X) GPU_select_load_id(MAN_TRANS_X);
- }
- else {
- manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->tw_idot[0]));
- }
- immBegin(GL_LINES, 2);
- immVertex3f(pos, 0.2f, 0.0f, 0.0f);
- immVertex3f(pos, 1.0f, 0.0f, 0.0f);
- immEnd();
+ switch (axis_type) {
+ case MAN_AXES_TRANSLATE:
+ if (v3d->twtype & V3D_MANIP_SCALE) {
+ *r_start = *r_len - ofs + 0.075f;
}
- break;
- case 1:
- if (flagy) {
- if (is_picksel) {
- if (flagy & MAN_SCALE_Y) GPU_select_load_id(MAN_SCALE_Y);
- else if (flagy & MAN_TRANS_Y) GPU_select_load_id(MAN_TRANS_Y);
- }
- else {
- manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->tw_idot[1]));
- }
- immBegin(GL_LINES, 2);
- immVertex3f(pos, 0.0f, 0.2f, 0.0f);
- immVertex3f(pos, 0.0f, 1.0f, 0.0f);
- immEnd();
+ if (v3d->twtype & V3D_MANIP_ROTATE) {
+ *r_len += ofs;
}
break;
- case 2:
- if (flagz) {
- if (is_picksel) {
- if (flagz & MAN_SCALE_Z) GPU_select_load_id(MAN_SCALE_Z);
- else if (flagz & MAN_TRANS_Z) GPU_select_load_id(MAN_TRANS_Z);
- }
- else {
- manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->tw_idot[2]));
- }
- immBegin(GL_LINES, 2);
- immVertex3f(pos, 0.0f, 0.0f, 0.2f);
- immVertex3f(pos, 0.0f, 0.0f, 1.0f);
- immEnd();
+ case MAN_AXES_SCALE:
+ if (v3d->twtype & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE)) {
+ *r_len -= ofs + 0.025f;
}
break;
}
-}
-static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode,
- int flagx, int flagy, int flagz,
- const int axis_order[3], const bool is_picksel, unsigned int pos)
-{
- int i;
- for (i = 0; i < 3; i++) {
- draw_manipulator_axes_single(v3d, rv3d, colcode, flagx, flagy, flagz, axis_order[i], is_picksel, pos);
- }
-}
-
-static void preOrthoFront(const bool ortho, float twmat[4][4], int axis)
-{
- if (ortho == false) {
- float omat[4][4];
- copy_m4_m4(omat, twmat);
- orthogonalize_m4(omat, axis);
- gpuPushMatrix();
- gpuMultMatrix3D(omat);
- glFrontFace(is_negative_m4(omat) ? GL_CW : GL_CCW);
- }
-}
-static void postOrtho(const bool ortho)
-{
- if (ortho == false) {
- gpuPopMatrix();
- }
+ *r_len -= *r_start;
}
-static void twmat_to_rotation_axis_mat(
- const float twmat[4][4], const int axis, const bool ortho,
- float r_axis_mat[4][4])
-{
- copy_m4_m4(r_axis_mat, twmat);
- if (!ortho) {
- orthogonalize_m4(r_axis_mat, axis); /* for gimbal */
- }
-
- if (ELEM(axis, 0, 1)) {
- const char rot_axis = (axis == 0) ? 'Y' : 'X';
- const float angle = (axis == 0) ? M_PI_2 : -M_PI_2;
- rotate_m4(r_axis_mat, rot_axis, angle);
- }
-}
+/* **************** Actual Widget Stuff **************** */
-BLI_INLINE bool manipulator_rotate_is_visible(const int drawflags)
+static ManipulatorGroup *manipulatorgroup_init(wmManipulatorGroup *wgroup)
{
- return (drawflags & (MAN_ROT_X | MAN_ROT_Y | MAN_ROT_Z));
+ ManipulatorGroup *man;
+
+ man = MEM_callocN(sizeof(ManipulatorGroup), "manipulator_data");
+
+ /* add/init widgets - order matters! */
+ man->rotate_t = MANIPULATOR_dial_new(wgroup, "rotate_t", MANIPULATOR_DIAL_STYLE_RING_FILLED);
+
+ man->scale_c = MANIPULATOR_dial_new(wgroup, "scale_c", MANIPULATOR_DIAL_STYLE_RING);
+ man->scale_x = MANIPULATOR_arrow_new(wgroup, "scale_x", MANIPULATOR_ARROW_STYLE_BOX);
+ man->scale_y = MANIPULATOR_arrow_new(wgroup, "scale_y", MANIPULATOR_ARROW_STYLE_BOX);
+ man->scale_z = MANIPULATOR_arrow_new(wgroup, "scale_z", MANIPULATOR_ARROW_STYLE_BOX);
+ man->scale_xy = MANIPULATOR_primitive_new(wgroup, "scale_xy", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+ man->scale_yz = MANIPULATOR_primitive_new(wgroup, "scale_yz", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+ man->scale_zx = MANIPULATOR_primitive_new(wgroup, "scale_zx", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+
+ man->rotate_x = MANIPULATOR_dial_new(wgroup, "rotate_x", MANIPULATOR_DIAL_STYLE_RING_CLIPPED);
+ man->rotate_y = MANIPULATOR_dial_new(wgroup, "rotate_y", MANIPULATOR_DIAL_STYLE_RING_CLIPPED);
+ man->rotate_z = MANIPULATOR_dial_new(wgroup, "rotate_z", MANIPULATOR_DIAL_STYLE_RING_CLIPPED);
+ /* init screen aligned widget last here, looks better, behaves better */
+ man->rotate_c = MANIPULATOR_dial_new(wgroup, "rotate_c", MANIPULATOR_DIAL_STYLE_RING);
+
+ man->translate_c = MANIPULATOR_dial_new(wgroup, "translate_c", MANIPULATOR_DIAL_STYLE_RING);
+ man->translate_x = MANIPULATOR_arrow_new(wgroup, "translate_x", MANIPULATOR_ARROW_STYLE_NORMAL);
+ man->translate_y = MANIPULATOR_arrow_new(wgroup, "translate_y", MANIPULATOR_ARROW_STYLE_NORMAL);
+ man->translate_z = MANIPULATOR_arrow_new(wgroup, "translate_z", MANIPULATOR_ARROW_STYLE_NORMAL);
+ man->translate_xy = MANIPULATOR_primitive_new(wgroup, "translate_xy", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+ man->translate_yz = MANIPULATOR_primitive_new(wgroup, "translate_yz", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+ man->translate_zx = MANIPULATOR_primitive_new(wgroup, "translate_zx", MANIPULATOR_PRIMITIVE_STYLE_PLANE);
+
+ return man;
}
-static void draw_manipulator_rotate(
- View3D *v3d, RegionView3D *rv3d, const int drawflags, const int combo,
- const bool is_moving, const bool is_picksel)
+/**
+ * Custom handler for manipulator widgets
+ */
+static int manipulator_handler(bContext *C, const wmEvent *UNUSED(event), wmManipulator *widget, const int UNUSED(flag))
{
- float matt[4][4];
- float size, unitmat[4][4];
- float cywid = 0.33f * 0.01f * (float)U.tw_handlesize;
- float cusize = cywid * 0.65f;
- bool arcs = (G.debug_value != 2);
- const int colcode = (is_moving) ? MAN_MOVECOL : MAN_RGB;
- bool ortho;
-
- /* skip drawing if all axes are locked */
- if (manipulator_rotate_is_visible(drawflags) == false) return;
-
- /* Init stuff */
- glDisable(GL_DEPTH_TEST);
- unit_m4(unitmat);
-
-
- /* prepare for screen aligned draw */
- size = len_v3(rv3d->twmat[0]);
- gpuPushMatrix();
- gpuTranslate3fv(rv3d->twmat[3]);
-
-
- const unsigned pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
-
- /* sets view screen aligned */
- gpuRotate3f(-360.0f * saacos(rv3d->viewquat[0]) / (float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
- /* Screen aligned help circle */
- if (arcs) {
- if (is_picksel == false) {
- immUniformThemeColorShade(TH_BACK, -30);
- imm_drawcircball(unitmat[3], size, unitmat, pos);
- }
- }
-
- /* Screen aligned trackball rot circle */
- if (drawflags & MAN_ROT_T) {
- if (is_picksel) GPU_select_load_id(MAN_ROT_T);
- else immUniformThemeColor(TH_TRANSFORM);
-
- imm_drawcircball(unitmat[3], 0.2f * size, unitmat, pos);
- }
-
- /* Screen aligned view rot circle */
- if (drawflags & MAN_ROT_V) {
- if (is_picksel) GPU_select_load_id(MAN_ROT_V);
- else immUniformThemeColor(TH_TRANSFORM);
- imm_drawcircball(unitmat[3], 1.2f * size, unitmat, pos);
-
- if (is_moving) {
- float vec[3];
- vec[0] = 0; // XXX (float)(t->mouse.imval[0] - t->center2d[0]);
- vec[1] = 0; // XXX (float)(t->mouse.imval[1] - t->center2d[1]);
- vec[2] = 0.0f;
- normalize_v3_length(vec, 1.2f * size);
- immBegin(GL_LINES, 2);
- immVertex3f(pos, 0.0f, 0.0f, 0.0f);
- immVertex3fv(pos,vec);
- immEnd();
- }
- }
- gpuPopMatrix();
-
- gpuPushMatrix();
-
- ortho = is_orthogonal_m4(rv3d->twmat);
-
- /* apply the transform delta */
- if (is_moving) {
- copy_m4_m4(matt, rv3d->twmat); // to copy the parts outside of [3][3]
- // XXX mul_m4_m3m4(matt, t->mat, rv3d->twmat);
- if (ortho) {
- gpuMultMatrix3D(matt);
- glFrontFace(is_negative_m4(matt) ? GL_CW : GL_CCW);
- }
- }
- else {
- if (ortho) {
- glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW : GL_CCW);
- gpuMultMatrix3D(rv3d->twmat);
- }
- }
-
- /* axes */
- if (arcs == false) {
- if (!is_picksel) {
- if ((combo & V3D_MANIP_SCALE) == 0) {
- /* axis */
- if ((drawflags & MAN_ROT_X) || (is_moving && (drawflags & MAN_ROT_Z))) {
- preOrthoFront(ortho, rv3d->twmat, 2);
- manipulator_setcolor(v3d, 'X', colcode, 255);
- immBegin(GL_LINES, 2);
- immVertex3f(pos, 0.2f, 0.0f, 0.0f);
- immVertex3f(pos, 1.0f, 0.0f, 0.0f);
- immEnd();
- postOrtho(ortho);
- }
- if ((drawflags & MAN_ROT_Y) || (is_moving && (drawflags & MAN_ROT_X))) {
- preOrthoFront(ortho, rv3d->twmat, 0);
- manipulator_setcolor(v3d, 'Y', colcode, 255);
- immBegin(GL_LINES, 2);
- immVertex3f(pos, 0.0f, 0.2f, 0.0f);
- immVertex3f(pos, 0.0f, 1.0f, 0.0f);
- immEnd();
- postOrtho(ortho);
- }
- if ((drawflags & MAN_ROT_Z) || (is_moving && (drawflags & MAN_ROT_Y))) {
- preOrthoFront(ortho, rv3d->twmat, 1);
- manipulator_setcolor(v3d, 'Z', colcode, 255);
- immBegin(GL_LINES, 2);
- immVertex3f(pos, 0.0f, 0.0f, 0.2f);
- immVertex3f(pos, 0.0f, 0.0f, 1.0f);
- immEnd();
- postOrtho(ortho);
- }
- }
- }
- }
-
- if (arcs == false && is_moving) {
-
- /* Z circle */
- if (drawflags & MAN_ROT_Z) {
- preOrthoFront(ortho, matt, 2);
- if (is_picksel) GPU_select_load_id(MAN_ROT_Z);
- else manipulator_setcolor(v3d, 'Z', colcode, 255);
- imm_drawcircball(unitmat[3], 1.0, unitmat, pos);
- postOrtho(ortho);
- }
- /* X circle */
- if (drawflags & MAN_ROT_X) {
- preOrthoFront(ortho, matt, 0);
- if (is_picksel) GPU_select_load_id(MAN_ROT_X);
- else manipulator_setcolor(v3d, 'X', colcode, 255);
- gpuPushMatrix();
- gpuRotateAxis(90.0, 'Y');
- imm_drawcircball(unitmat[3], 1.0, unitmat, pos);
- gpuPopMatrix();
- postOrtho(ortho);
- }
- /* Y circle */
- if (drawflags & MAN_ROT_Y) {
- preOrthoFront(ortho, matt, 1);
- if (is_picksel) GPU_select_load_id(MAN_ROT_Y);
- else manipulator_setcolor(v3d, 'Y', colcode, 255);
- gpuPushMatrix();
- gpuRotateAxis(-90.0, 'X');
- imm_drawcircball(unitmat[3], 1.0, unitmat, pos);
- gpuPopMatrix();
- postOrtho(ortho);
- }
- }
- // donut arcs
- if (arcs) {
- float axis_model_mat[4][4];
-
-#if !APPLE_LEGACY
- float clip_plane[4];
-
- copy_v3_v3(clip_plane, rv3d->viewinv[2]);
- clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], rv3d->twmat[3]);
- clip_plane[3] -= 0.02f * size; /* clip just a bit more so view aligned arcs are not visible */
-#endif
-
- gpuPopMatrix(); /* we setup our own matrix, pop previously set twmat */
-
-#if !APPLE_LEGACY
- immUnbindProgram();
- immBindBuiltinProgram(GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR);
- immUniform4fv("ClipPlane", clip_plane);
-
- glEnable(GL_CLIP_DISTANCE0);
-#endif
-
- /* Z circle */
- if (drawflags & MAN_ROT_Z) {
- if (is_picksel) GPU_select_load_id(MAN_ROT_Z);
- else manipulator_setcolor(v3d, 'Z', colcode, 255);
-
- twmat_to_rotation_axis_mat(rv3d->twmat, 2, ortho, axis_model_mat);
-#if !APPLE_LEGACY
- immUniformMatrix4fv("ModelMatrix", axis_model_mat);
-#endif
- gpuPushMatrix();
- gpuMultMatrix3D(axis_model_mat);
-
- partial_doughnut(pos, cusize / 4.0f, 1.0f, 0, 48, 8, 48);
- gpuPopMatrix();
- }
- /* X circle */
- if (drawflags & MAN_ROT_X) {
- if (is_picksel) GPU_select_load_id(MAN_ROT_X);
- else manipulator_setcolor(v3d, 'X', colcode, 255);
-
- twmat_to_rotation_axis_mat(rv3d->twmat, 0, ortho, axis_model_mat);
-#if !APPLE_LEGACY
- immUniformMatrix4fv("ModelMatrix", axis_model_mat);
-#endif
- gpuPushMatrix();
- gpuMultMatrix3D(axis_model_mat);
-
- partial_doughnut(pos, cusize / 4.0f, 1.0f, 0, 48, 8, 48);
- gpuPopMatrix();
- }
- /* Y circle */
- if (drawflags & MAN_ROT_Y) {
- if (is_picksel) GPU_select_load_id(MAN_ROT_Y);
- else manipulator_setcolor(v3d, 'Y', colcode, 255);
-
- twmat_to_rotation_axis_mat(rv3d->twmat, 1, ortho, axis_model_mat);
-#if !APPLE_LEGACY
- immUniformMatrix4fv("ModelMatrix", axis_model_mat);
-#endif
- gpuPushMatrix();
- gpuMultMatrix3D(axis_model_mat);
-
- partial_doughnut(pos, cusize / 4.0f, 1.0f, 0, 48, 8, 48);
- gpuPopMatrix();
- }
-
-#if !APPLE_LEGACY
- glDisable(GL_CLIP_DISTANCE0);
-#endif
-
- gpuPushMatrix(); /* to balance final pop at end of function */
- }
- else {
-
- /* Z handle on X axis */
- if (drawflags & MAN_ROT_Z) {
- preOrthoFront(ortho, rv3d->twmat, 2);
- gpuPushMatrix();
- if (is_picksel) GPU_select_load_id(MAN_ROT_Z);
- else manipulator_setcolor(v3d, 'Z', colcode, 255);
-
- partial_doughnut(pos, 0.7f * cusize, 1.0f, 31, 33, 8, 64);
-
- gpuPopMatrix();
- postOrtho(ortho);
- }
-
- /* Y handle on X axis */
- if (drawflags & MAN_ROT_Y) {
- preOrthoFront(ortho, rv3d->twmat, 1);
- gpuPushMatrix();
- if (is_picksel) GPU_select_load_id(MAN_ROT_Y);
- else manipulator_setcolor(v3d, 'Y', colcode, 255);
-
- gpuRotateAxis(90.0, 'X');
- gpuRotateAxis(90.0, 'Z');
- partial_doughnut(pos, 0.7f * cusize, 1.0f, 31, 33, 8, 64);
-
- gpuPopMatrix();
- postOrtho(ortho);
- }
-
- /* X handle on Z axis */
- if (drawflags & MAN_ROT_X) {
- preOrthoFront(ortho, rv3d->twmat, 0);
- gpuPushMatrix();
- if (is_picksel) GPU_select_load_id(MAN_ROT_X);
- else manipulator_setcolor(v3d, 'X', colcode, 255);
-
- gpuRotateAxis(-90.0, 'Y');
- gpuRotateAxis(90.0, 'Z');
- partial_doughnut(pos, 0.7f * cusize, 1.0f, 31, 33, 8, 64);
+ const ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = sa->spacedata.first;
+ RegionView3D *rv3d = ar->regiondata;
- gpuPopMatrix();
- postOrtho(ortho);
- }
+ if (calc_manipulator_stats(C)) {
+ manipulator_prepare_mat(C, v3d, rv3d);
+ WM_manipulator_set_origin(widget, rv3d->twmat[3]);
}
- /* Note: Shader is not ensured to be GPU_SHADER_3D_UNIFORM_COLOR from here on, twmat might have been popped too! */
-
- /* restore */
- gpuPopMatrix();
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
- immUnbindProgram();
-}
+ ED_region_tag_redraw(ar);
-static void drawsolidcube(unsigned int pos, float size)
-{
- const float cube[8][3] = {
- {-1.0, -1.0, -1.0},
- {-1.0, -1.0, 1.0},
- {-1.0, 1.0, 1.0},
- {-1.0, 1.0, -1.0},
- { 1.0, -1.0, -1.0},
- { 1.0, -1.0, 1.0},
- { 1.0, 1.0, 1.0},
- { 1.0, 1.0, -1.0},
- };
-
- gpuPushMatrix();
- gpuScaleUniform(size);
-
- immBegin(GL_TRIANGLES, 12 * 3);
- immVertex3fv(pos, cube[0]); immVertex3fv(pos, cube[1]); immVertex3fv(pos, cube[2]);
- immVertex3fv(pos, cube[0]); immVertex3fv(pos, cube[2]); immVertex3fv(pos, cube[3]);
- immVertex3fv(pos, cube[0]); immVertex3fv(pos, cube[4]); immVertex3fv(pos, cube[5]);
- immVertex3fv(pos, cube[0]); immVertex3fv(pos, cube[5]); immVertex3fv(pos, cube[1]);
- immVertex3fv(pos, cube[4]); immVertex3fv(pos, cube[7]); immVertex3fv(pos, cube[6]);
- immVertex3fv(pos, cube[4]); immVertex3fv(pos, cube[6]); immVertex3fv(pos, cube[5]);
- immVertex3fv(pos, cube[7]); immVertex3fv(pos, cube[3]); immVertex3fv(pos, cube[2]);
- immVertex3fv(pos, cube[7]); immVertex3fv(pos, cube[2]); immVertex3fv(pos, cube[6]);
- immVertex3fv(pos, cube[1]); immVertex3fv(pos, cube[5]); immVertex3fv(pos, cube[6]);
- immVertex3fv(pos, cube[1]); immVertex3fv(pos, cube[6]); immVertex3fv(pos, cube[2]);
- immVertex3fv(pos, cube[7]); immVertex3fv(pos, cube[4]); immVertex3fv(pos, cube[0]);
- immVertex3fv(pos, cube[7]); immVertex3fv(pos, cube[0]); immVertex3fv(pos, cube[3]);
- immEnd();
-
- gpuPopMatrix();
+ return OPERATOR_PASS_THROUGH;
}
-
-static void draw_manipulator_scale(
- View3D *v3d, RegionView3D *rv3d, const int drawflags, const int combo, const int colcode,
- const bool is_moving, const bool is_picksel)
+static void WIDGETGROUP_manipulator_init(const bContext *UNUSED(C), wmManipulatorGroup *wgroup)
{
- float cywid = 0.25f * 0.01f * (float)U.tw_handlesize;
- float cusize = cywid * 0.75f, dz;
- int axis_order[3] = {2, 0, 1};
- int i;
-
- /* when called while moving in mixed mode, do not draw when... */
- if ((drawflags & MAN_SCALE_C) == 0) return;
-
- manipulator_axis_order(rv3d, axis_order);
-
- glDisable(GL_DEPTH_TEST);
-
- const unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
- gpuPushMatrix();
-
- /* not in combo mode */
- if ((combo & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE)) == 0) {
- float size, unitmat[4][4];
- int shift = 0; // XXX
-
- /* center circle, do not add to selection when shift is pressed (planar constraint) */
- if (is_picksel && shift == 0) GPU_select_load_id(MAN_SCALE_C);
- else manipulator_setcolor(v3d, 'C', colcode, 255);
-
- gpuPushMatrix();
- size = screen_aligned(rv3d, rv3d->twmat);
- unit_m4(unitmat);
- imm_drawcircball(unitmat[3], 0.2f * size, unitmat, pos);
- gpuPopMatrix();
-
- dz = 1.0;
- }
- else {
- dz = 1.0f - 4.0f * cusize;
- }
-
- if (is_moving) {
- float matt[4][4];
-
- copy_m4_m4(matt, rv3d->twmat); // to copy the parts outside of [3][3]
- // XXX mul_m4_m3m4(matt, t->mat, rv3d->twmat);
- gpuMultMatrix3D(matt);
- glFrontFace(is_negative_m4(matt) ? GL_CW : GL_CCW);
- }
- else {
- gpuMultMatrix3D(rv3d->twmat);
- glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW : GL_CCW);
- }
-
- /* axis */
+ ManipulatorGroup *man = manipulatorgroup_init(wgroup);
+ wgroup->customdata = man;
- /* in combo mode, this is always drawn as first type */
- draw_manipulator_axes(v3d, rv3d, colcode,
- drawflags & MAN_SCALE_X, drawflags & MAN_SCALE_Y, drawflags & MAN_SCALE_Z,
- axis_order, is_picksel, pos);
+ /* *** set properties for axes *** */
-
- for (i = 0; i < 3; i++) {
- switch (axis_order[i]) {
- case 0: /* X cube */
- if (drawflags & MAN_SCALE_X) {
- gpuTranslate3f(dz, 0.0, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_SCALE_X);
- else manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->tw_idot[0]));
- drawsolidcube(pos, cusize);
- gpuTranslate3f(-dz, 0.0, 0.0);
- }
+ MAN_ITER_AXES_BEGIN(axis, axis_idx)
+ {
+ const short axis_type = manipulator_get_axis_type(man, axis);
+ int constraint_axis[3] = {1, 0, 0};
+ PointerRNA *ptr;
+
+ manipulator_get_axis_constraint(axis_idx, constraint_axis);
+
+ /* custom handler! */
+ WM_manipulator_set_custom_handler(axis, manipulator_handler);
+
+ switch(axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_SCALE_X:
+ case MAN_AXIS_SCALE_Y:
+ case MAN_AXIS_SCALE_Z:
+ WM_manipulator_set_line_width(axis, MANIPULATOR_AXIS_LINE_WIDTH);
break;
- case 1: /* Y cube */
- if (drawflags & MAN_SCALE_Y) {
- gpuTranslate3f(0.0, dz, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_SCALE_Y);
- else manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->tw_idot[1]));
- drawsolidcube(pos, cusize);
- gpuTranslate3f(0.0, -dz, 0.0);
- }
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_ROT_Z:
+ /* increased line width for better display */
+ WM_manipulator_set_line_width(axis, MANIPULATOR_AXIS_LINE_WIDTH + 1.0f);
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_DRAW_VALUE, true);
break;
- case 2: /* Z cube */
- if (drawflags & MAN_SCALE_Z) {
- gpuTranslate3f(0.0, 0.0, dz);
- if (is_picksel) GPU_select_load_id(MAN_SCALE_Z);
- else manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->tw_idot[2]));
- drawsolidcube(pos, cusize);
- gpuTranslate3f(0.0, 0.0, -dz);
- }
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_XY:
+ case MAN_AXIS_SCALE_YZ:
+ case MAN_AXIS_SCALE_ZX:
+ {
+ const float ofs_ax = 11.0f;
+ const float ofs[3] = {ofs_ax, ofs_ax, 0.0f};
+ WM_manipulator_set_scale(axis, 0.07f);
+ WM_manipulator_set_offset(axis, ofs);
break;
- }
- }
-
-#if 0 // XXX
- /* if shiftkey, center point as last, for selectbuffer order */
- if (is_picksel) {
- int shift = 0; // XXX
-
- if (shift) {
- gpuTranslate3f(0.0, -dz, 0.0);
- GPU_select_load_id(MAN_SCALE_C);
- /* TODO: set glPointSize before drawing center point */
- immBegin(GL_POINTS, 1);
- immVertex3f(0.0, 0.0, 0.0);
- immEnd();
- }
- }
-#endif
-
- /* restore */
- gpuPopMatrix();
-
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
- glFrontFace(GL_CCW);
-
- immUnbindProgram();
-}
-
-#define NSEGMENTS 8
-static void draw_cone(unsigned int pos, float len, float width)
-{
- /* a ring of vertices in the XY plane */
- float p[NSEGMENTS][2];
- for (int i = 0; i < NSEGMENTS; ++i) {
- float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
- p[i][0] = width * cosf(angle);
- p[i][1] = width * sinf(angle);
- }
-
- float zbase = -0.5f * len;
- float ztop = 0.5f * len;
-
- /* cone sides */
- immBegin(GL_TRIANGLE_FAN, NSEGMENTS + 2);
- immVertex3f(pos, 0, 0, ztop);
- for (int i = 0; i < NSEGMENTS; ++i)
- immVertex3f(pos, p[i][0], p[i][1], zbase);
- immVertex3f(pos, p[0][0], p[0][1], zbase);
- immEnd();
-
- /* end cap */
- immBegin(GL_TRIANGLE_FAN, NSEGMENTS);
- for (int i = NSEGMENTS - 1; i >= 0; --i)
- immVertex3f(pos, p[i][0], p[i][1], zbase);
- immEnd();
-}
-
-static void draw_cylinder(unsigned int pos, float len, float width)
-{
- width *= 0.8f; // just for beauty
-
- /* a ring of vertices in the XY plane */
- float p[NSEGMENTS][2];
- for (int i = 0; i < NSEGMENTS; ++i) {
- float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
- p[i][0] = width * cosf(angle);
- p[i][1] = width * sinf(angle);
- }
-
- float zbase = -0.5f * len;
- float ztop = 0.5f * len;
-
- /* cylinder sides */
- immBegin(GL_TRIANGLE_STRIP, (NSEGMENTS + 1) * 2);
- for (int i = 0; i < NSEGMENTS; ++i) {
- immVertex3f(pos, p[i][0], p[i][1], zbase);
- immVertex3f(pos, p[i][0], p[i][1], ztop);
- }
- immVertex3f(pos, p[0][0], p[0][1], zbase);
- immVertex3f(pos, p[0][0], p[0][1], ztop);
- immEnd();
-
- /* end caps */
- immBegin(GL_TRIANGLE_FAN, NSEGMENTS);
- for (int i = NSEGMENTS - 1; i >= 0; --i)
- immVertex3f(pos, p[i][0], p[i][1], zbase);
- immEnd();
- immBegin(GL_TRIANGLE_FAN, NSEGMENTS);
- for (int i = 0; i < NSEGMENTS; ++i)
- immVertex3f(pos, p[i][0], p[i][1], ztop);
- immEnd();
-}
-#undef NSEGMENTS
-
-static void draw_manipulator_translate(
- View3D *v3d, RegionView3D *rv3d, int drawflags, int combo, int colcode,
- const bool UNUSED(is_moving), const bool is_picksel)
-{
- float cylen = 0.01f * (float)U.tw_handlesize;
- float cywid = 0.25f * cylen, dz, size;
- float unitmat[4][4];
- int shift = 0; // XXX
- int axis_order[3] = {0, 1, 2};
- int i;
-
- /* when called while moving in mixed mode, do not draw when... */
- if ((drawflags & MAN_TRANS_C) == 0) return;
-
- manipulator_axis_order(rv3d, axis_order);
-
- // XXX if (moving) gpuTranslate3fv(t->vec);
- glDisable(GL_DEPTH_TEST);
-
- const unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
- gpuPushMatrix();
-
- /* center circle, do not add to selection when shift is pressed (planar constraint) */
- if (is_picksel && shift == 0) GPU_select_load_id(MAN_TRANS_C);
- else manipulator_setcolor(v3d, 'C', colcode, 255);
-
- gpuPushMatrix();
- size = screen_aligned(rv3d, rv3d->twmat);
- unit_m4(unitmat);
- imm_drawcircball(unitmat[3], 0.2f * size, unitmat, pos);
- gpuPopMatrix();
-
- /* and now apply matrix, we move to local matrix drawing */
- gpuMultMatrix3D(rv3d->twmat);
-
- /* axis */
- GPU_select_load_id(-1);
-
- // translate drawn as last, only axis when no combo with scale, or for ghosting
- if ((combo & V3D_MANIP_SCALE) == 0 || colcode == MAN_GHOST) {
- draw_manipulator_axes(v3d, rv3d, colcode,
- drawflags & MAN_TRANS_X, drawflags & MAN_TRANS_Y, drawflags & MAN_TRANS_Z,
- axis_order, is_picksel, pos);
- }
-
- /* offset in combo mode, for rotate a bit more */
- if (combo & (V3D_MANIP_ROTATE)) dz = 1.0f + 2.0f * cylen;
- else if (combo & (V3D_MANIP_SCALE)) dz = 1.0f + 0.5f * cylen;
- else dz = 1.0f;
-
- for (i = 0; i < 3; i++) {
- switch (axis_order[i]) {
- case 0: /* Z Cone */
- if (drawflags & MAN_TRANS_Z) {
- gpuPushMatrix();
- gpuTranslate3f(0.0, 0.0, dz);
- if (is_picksel) GPU_select_load_id(MAN_TRANS_Z);
- else manipulator_setcolor(v3d, 'Z', colcode, axisBlendAngle(rv3d->tw_idot[2]));
- draw_cone(pos, cylen, cywid);
- gpuPopMatrix();
+ }
+ case MAN_AXIS_TRANS_C:
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_SCALE_C:
+ case MAN_AXIS_ROT_T:
+ WM_manipulator_set_line_width(axis, MANIPULATOR_AXIS_LINE_WIDTH);
+ if (axis_idx == MAN_AXIS_ROT_T) {
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_DRAW_HOVER, true);
}
- break;
- case 1: /* X Cone */
- if (drawflags & MAN_TRANS_X) {
- gpuPushMatrix();
- gpuTranslate3f(dz, 0.0, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_TRANS_X);
- else manipulator_setcolor(v3d, 'X', colcode, axisBlendAngle(rv3d->tw_idot[0]));
- gpuRotateAxis(90.0, 'Y');
- draw_cone(pos, cylen, cywid);
- gpuPopMatrix();
+ else if (axis_idx == MAN_AXIS_ROT_C) {
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_DRAW_VALUE, true);
}
- break;
- case 2: /* Y Cone */
- if (drawflags & MAN_TRANS_Y) {
- gpuPushMatrix();
- gpuTranslate3f(0.0, dz, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_TRANS_Y);
- else manipulator_setcolor(v3d, 'Y', colcode, axisBlendAngle(rv3d->tw_idot[1]));
- gpuRotateAxis(-90.0, 'X');
- draw_cone(pos, cylen, cywid);
- gpuPopMatrix();
+ else {
+ WM_manipulator_set_scale(axis, 0.2f);
}
break;
}
- }
-
- gpuPopMatrix();
-
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
-
- immUnbindProgram();
-}
-
-static void draw_manipulator_rotate_cyl(
- View3D *v3d, RegionView3D *rv3d, int drawflags, const int combo, const int colcode,
- const bool is_moving, const bool is_picksel)
-{
- float size;
- float cylen = 0.01f * (float)U.tw_handlesize;
- float cywid = 0.25f * cylen;
- int axis_order[3] = {2, 0, 1};
- int i;
-
- /* skip drawing if all axes are locked */
- if (manipulator_rotate_is_visible(drawflags) == false) return;
-
- manipulator_axis_order(rv3d, axis_order);
-
- const unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
- gpuPushMatrix();
-
- /* prepare for screen aligned draw */
- gpuPushMatrix();
- size = screen_aligned(rv3d, rv3d->twmat);
-
- glDisable(GL_DEPTH_TEST);
-
- /* Screen aligned view rot circle */
- if (drawflags & MAN_ROT_V) {
- float unitmat[4][4];
-
- unit_m4(unitmat);
-
- if (is_picksel) GPU_select_load_id(MAN_ROT_V);
- immUniformThemeColor(TH_TRANSFORM);
- imm_drawcircball(unitmat[3], 1.2f * size, unitmat, pos);
-
- if (is_moving) {
- float vec[3];
- vec[0] = 0; // XXX (float)(t->mouse.imval[0] - t->center2d[0]);
- vec[1] = 0; // XXX (float)(t->mouse.imval[1] - t->center2d[1]);
- vec[2] = 0.0f;
- normalize_v3_length(vec, 1.2f * size);
- immBegin(GL_LINES, 2);
- immVertex3f(pos, 0.0, 0.0, 0.0);
- immVertex3fv(pos, vec);
- immEnd();
- }
- }
- gpuPopMatrix();
-
- /* apply the transform delta */
- if (is_moving) {
- float matt[4][4];
- copy_m4_m4(matt, rv3d->twmat); // to copy the parts outside of [3][3]
- // XXX if (t->flag & T_USES_MANIPULATOR) {
- // XXX mul_m4_m3m4(matt, t->mat, rv3d->twmat);
- // XXX }
- gpuMultMatrix3D(matt);
- }
- else {
- gpuMultMatrix3D(rv3d->twmat);
- }
-
- glFrontFace(is_negative_m4(rv3d->twmat) ? GL_CW : GL_CCW);
-
- /* axis */
- if (is_picksel == false) {
-
- // only draw axis when combo didn't draw scale axes
- if ((combo & V3D_MANIP_SCALE) == 0) {
- draw_manipulator_axes(v3d, rv3d, colcode,
- drawflags & MAN_ROT_X, drawflags & MAN_ROT_Y, drawflags & MAN_ROT_Z,
- axis_order, is_picksel, pos);
- }
- }
- for (i = 0; i < 3; i++) {
- switch (axis_order[i]) {
- case 0: /* X cylinder */
- if (drawflags & MAN_ROT_X) {
- gpuPushMatrix();
- gpuTranslate3f(1.0, 0.0, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_ROT_X);
- gpuRotateAxis(90.0, 'Y');
- manipulator_setcolor(v3d, 'X', colcode, 255);
- draw_cylinder(pos, cylen, cywid);
- gpuPopMatrix();
- }
+ switch (axis_type) {
+ case MAN_AXES_TRANSLATE:
+ ptr = WM_manipulator_set_operator(axis, "TRANSFORM_OT_translate");
break;
- case 1: /* Y cylinder */
- if (drawflags & MAN_ROT_Y) {
- gpuPushMatrix();
- gpuTranslate3f(0.0, 1.0, 0.0);
- if (is_picksel) GPU_select_load_id(MAN_ROT_Y);
- gpuRotateAxis(-90.0, 'X');
- manipulator_setcolor(v3d, 'Y', colcode, 255);
- draw_cylinder(pos, cylen, cywid);
- gpuPopMatrix();
- }
+ case MAN_AXES_ROTATE:
+ ptr = WM_manipulator_set_operator(
+ axis, (axis_idx == MAN_AXIS_ROT_T) ?
+ "TRANSFORM_OT_trackball" : "TRANSFORM_OT_rotate");
break;
- case 2: /* Z cylinder */
- if (drawflags & MAN_ROT_Z) {
- gpuPushMatrix();
- gpuTranslate3f(0.0, 0.0, 1.0);
- if (is_picksel) GPU_select_load_id(MAN_ROT_Z);
- manipulator_setcolor(v3d, 'Z', colcode, 255);
- draw_cylinder(pos, cylen, cywid);
- gpuPopMatrix();
- }
+ case MAN_AXES_SCALE:
+ ptr = WM_manipulator_set_operator(axis, "TRANSFORM_OT_resize");
break;
}
+ if (RNA_struct_find_property(ptr, "constraint_axis"))
+ RNA_boolean_set_array(ptr, "constraint_axis", constraint_axis);
+ RNA_boolean_set(ptr, "release_confirm", 1);
}
-
- /* restore */
- gpuPopMatrix();
-
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
-
- immUnbindProgram();
+ MAN_ITER_AXES_END;
}
-
-/* ********************************************* */
-
-/* main call, does calc centers & orientation too */
-static int drawflags = 0xFFFF; // only for the calls below, belongs in scene...?
-
-void BIF_draw_manipulator(const bContext *C)
+static void WIDGETGROUP_manipulator_refresh(const bContext *C, wmManipulatorGroup *wgroup)
{
+ ManipulatorGroup *man = wgroup->customdata;
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
- SceneLayer *sl = CTX_data_scene_layer(C);
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
- int totsel;
- const bool is_picksel = false;
+ /* skip, we don't draw anything anyway */
+ if ((man->all_hidden = (calc_manipulator_stats(C) == 0)))
+ return;
- if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return;
+ manipulator_prepare_mat(C, v3d, rv3d);
- if ((v3d->twtype & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE | V3D_MANIP_SCALE)) == 0) return;
+ /* *** set properties for axes *** */
+ MAN_ITER_AXES_BEGIN(axis, axis_idx)
{
- v3d->twflag &= ~V3D_DRAW_MANIPULATOR;
-
- totsel = calc_manipulator_stats(C);
- if (totsel == 0) return;
-
- v3d->twflag |= V3D_DRAW_MANIPULATOR;
-
- /* now we can define center */
- switch (v3d->around) {
- case V3D_AROUND_CENTER_BOUNDS:
- case V3D_AROUND_ACTIVE:
+ const short axis_type = manipulator_get_axis_type(man, axis);
+ const int aidx_norm = manipulator_index_normalize(axis_idx);
+
+ WM_manipulator_set_origin(axis, rv3d->twmat[3]);
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_SCALE_X:
+ case MAN_AXIS_SCALE_Y:
+ case MAN_AXIS_SCALE_Z:
{
- bGPdata *gpd = CTX_data_gpencil_data(C);
- Object *ob = OBACT_NEW;
+ float start_co[3] = {0.0f, 0.0f, 0.0f};
+ float len;
- if (((v3d->around == V3D_AROUND_ACTIVE) && (scene->obedit == NULL)) &&
- ((gpd == NULL) || !(gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
- (ob && !(ob->mode & OB_MODE_POSE)))
- {
- copy_v3_v3(rv3d->twmat[3], ob->obmat[3]);
- }
- else {
- mid_v3_v3v3(rv3d->twmat[3], scene->twmin, scene->twmax);
- }
+ manipulator_line_range(v3d, axis_type, &start_co[2], &len);
+
+ MANIPULATOR_arrow_set_direction(axis, rv3d->twmat[aidx_norm]);
+ MANIPULATOR_arrow_set_line_len(axis, len);
+ WM_manipulator_set_offset(axis, start_co);
break;
}
- case V3D_AROUND_LOCAL_ORIGINS:
- case V3D_AROUND_CENTER_MEAN:
- copy_v3_v3(rv3d->twmat[3], scene->twcent);
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_ROT_Z:
+ MANIPULATOR_dial_set_up_vector(axis, rv3d->twmat[aidx_norm]);
break;
- case V3D_AROUND_CURSOR:
- copy_v3_v3(rv3d->twmat[3], ED_view3d_cursor3d_get(scene, v3d));
+ case MAN_AXIS_TRANS_XY:
+ case MAN_AXIS_TRANS_YZ:
+ case MAN_AXIS_TRANS_ZX:
+ case MAN_AXIS_SCALE_XY:
+ case MAN_AXIS_SCALE_YZ:
+ case MAN_AXIS_SCALE_ZX:
+ MANIPULATOR_primitive_set_direction(axis, rv3d->twmat[aidx_norm - 1 < 0 ? 2 : aidx_norm - 1]);
+ MANIPULATOR_primitive_set_up_vector(axis, rv3d->twmat[aidx_norm + 1 > 2 ? 0 : aidx_norm + 1]);
break;
}
-
- mul_mat3_m4_fl(rv3d->twmat, ED_view3d_pixel_size(rv3d, rv3d->twmat[3]) * U.tw_size);
- }
-
- /* when looking through a selected camera, the manipulator can be at the
- * exact same position as the view, skip so we don't break selection */
- if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f)
- return;
-
- test_manipulator_axis(C);
- drawflags = rv3d->twdrawflag; /* set in calc_manipulator_stats */
-
- if (v3d->twflag & V3D_DRAW_MANIPULATOR) {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glLineWidth(1.0f);
-
- if (v3d->twtype & V3D_MANIP_ROTATE) {
- if (G.debug_value == 3) {
- if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT))
- draw_manipulator_rotate_cyl(v3d, rv3d, drawflags, v3d->twtype, MAN_MOVECOL, true, is_picksel);
- else
- draw_manipulator_rotate_cyl(v3d, rv3d, drawflags, v3d->twtype, MAN_RGB, false, is_picksel);
- }
- else {
- draw_manipulator_rotate(v3d, rv3d, drawflags, v3d->twtype, false, is_picksel);
- }
- }
- if (v3d->twtype & V3D_MANIP_SCALE) {
- draw_manipulator_scale(v3d, rv3d, drawflags, v3d->twtype, MAN_RGB, false, is_picksel);
- }
- if (v3d->twtype & V3D_MANIP_TRANSLATE) {
- draw_manipulator_translate(v3d, rv3d, drawflags, v3d->twtype, MAN_RGB, false, is_picksel);
- }
-
- glDisable(GL_BLEND);
}
+ MAN_ITER_AXES_END;
}
-static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], float hotspot)
+static void WIDGETGROUP_manipulator_draw_prepare(const bContext *C, wmManipulatorGroup *wgroup)
{
+ ManipulatorGroup *man = wgroup->customdata;
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
- rcti rect;
- GLuint buffer[64]; // max 4 items per select, so large enuf
- short hits;
- const bool is_picksel = true;
- const bool do_passes = GPU_select_query_check_active();
-
- /* XXX check a bit later on this... (ton) */
- extern void view3d_winmatrix_set(ARegion *ar, View3D *v3d, const rcti *rect);
+ float idot[3];
/* when looking through a selected camera, the manipulator can be at the
* exact same position as the view, skip so we don't break selection */
- if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f)
- return 0;
-
- rect.xmin = mval[0] - hotspot;
- rect.xmax = mval[0] + hotspot;
- rect.ymin = mval[1] - hotspot;
- rect.ymax = mval[1] + hotspot;
-
- view3d_winmatrix_set(ar, v3d, &rect);
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
-
- if (do_passes)
- GPU_select_begin(buffer, 64, &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
- else
- GPU_select_begin(buffer, 64, &rect, GPU_SELECT_ALL, 0);
-
- /* do the drawing */
- if (v3d->twtype & V3D_MANIP_ROTATE) {
- if (G.debug_value == 3) draw_manipulator_rotate_cyl(v3d, rv3d, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
- else draw_manipulator_rotate(v3d, rv3d, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype, false, is_picksel);
+ if (man->all_hidden || fabsf(ED_view3d_pixel_size(rv3d, rv3d->twmat[3])) < 1e-6f) {
+ MAN_ITER_AXES_BEGIN(axis, axis_idx)
+ {
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_HIDDEN, true);
+ }
+ MAN_ITER_AXES_END;
+ return;
}
- if (v3d->twtype & V3D_MANIP_SCALE)
- draw_manipulator_scale(v3d, rv3d, MAN_SCALE_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
- if (v3d->twtype & V3D_MANIP_TRANSLATE)
- draw_manipulator_translate(v3d, rv3d, MAN_TRANS_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
+ manipulator_get_idot(rv3d, idot);
- hits = GPU_select_end();
+ /* *** set properties for axes *** */
- if (do_passes) {
- GPU_select_begin(buffer, 64, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
-
- /* do the drawing */
- if (v3d->twtype & V3D_MANIP_ROTATE) {
- if (G.debug_value == 3) draw_manipulator_rotate_cyl(v3d, rv3d, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
- else draw_manipulator_rotate(v3d, rv3d, MAN_ROT_C & rv3d->twdrawflag, v3d->twtype, false, is_picksel);
+ MAN_ITER_AXES_BEGIN(axis, axis_idx)
+ {
+ const short axis_type = manipulator_get_axis_type(man, axis);
+ /* XXX maybe unset _HIDDEN flag on redraw? */
+ if (manipulator_is_axis_visible(v3d, rv3d, idot, axis_type, axis_idx)) {
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_HIDDEN, false);
+ }
+ else {
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_HIDDEN, true);
+ continue;
}
- if (v3d->twtype & V3D_MANIP_SCALE)
- draw_manipulator_scale(v3d, rv3d, MAN_SCALE_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
- if (v3d->twtype & V3D_MANIP_TRANSLATE)
- draw_manipulator_translate(v3d, rv3d, MAN_TRANS_C & rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
- GPU_select_end();
- }
+ float col[4], col_hi[4];
+ manipulator_get_axis_color(axis_idx, idot, col, col_hi);
+ WM_manipulator_set_colors(axis, col, col_hi);
- view3d_winmatrix_set(ar, v3d, NULL);
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_C:
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_SCALE_C:
+ case MAN_AXIS_ROT_T:
+ MANIPULATOR_dial_set_up_vector(axis, rv3d->viewinv[2]);
+ break;
+ }
+ }
+ MAN_ITER_AXES_END;
+}
- if (hits == 1) return buffer[3];
- else if (hits > 1) {
- GLuint val, dep, mindep = 0, mindeprot = 0, minval = 0, minvalrot = 0;
- int a;
+static bool WIDGETGROUP_manipulator_poll(const struct bContext *C, struct wmManipulatorGroupType *UNUSED(wgrouptype))
+{
+ /* it's a given we only use this in 3D view */
+ const ScrArea *sa = CTX_wm_area(C);
+ const View3D *v3d = sa->spacedata.first;
- /* we compare the hits in buffer, but value centers highest */
- /* we also store the rotation hits separate (because of arcs) and return hits on other widgets if there are */
+ return (((v3d->twflag & V3D_USE_MANIPULATOR) != 0) &&
+ ((v3d->twtype & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE | V3D_MANIP_SCALE)) != 0));
+}
- for (a = 0; a < hits; a++) {
- dep = buffer[4 * a + 1];
- val = buffer[4 * a + 3];
+void TRANSFORM_WGT_manipulator(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Transform Manipulator";
- if (val == MAN_TRANS_C) {
- return MAN_TRANS_C;
- }
- else if (val == MAN_SCALE_C) {
- return MAN_SCALE_C;
- }
- else {
- if (val & MAN_ROT_C) {
- if (minvalrot == 0 || dep < mindeprot) {
- mindeprot = dep;
- minvalrot = val;
- }
- }
- else {
- if (minval == 0 || dep < mindep) {
- mindep = dep;
- minval = val;
- }
- }
- }
- }
+ wgt->poll = WIDGETGROUP_manipulator_poll;
+ wgt->init = WIDGETGROUP_manipulator_init;
+ wgt->refresh = WIDGETGROUP_manipulator_refresh;
+ wgt->draw_prepare = WIDGETGROUP_manipulator_draw_prepare;
- if (minval)
- return minval;
- else
- return minvalrot;
- }
- return 0;
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_IS_3D | WM_MANIPULATORGROUPTYPE_SCALE_3D);
}
-static const char *manipulator_get_operator_name(int man_val)
+
+/* -------------------------------------------------------------------- */
+/* Custom Object Manipulator (unfinished - unsure if this will stay) */
+#if 0
+static void WIDGETGROUP_object_manipulator_init(const bContext *C, wmManipulatorGroup *wgroup)
{
- if (man_val & MAN_TRANS_C) {
- return "TRANSFORM_OT_translate";
- }
- else if (man_val == MAN_ROT_T) {
- return "TRANSFORM_OT_trackball";
- }
- else if (man_val & MAN_ROT_C) {
- return "TRANSFORM_OT_rotate";
- }
- else if (man_val & MAN_SCALE_C) {
- return "TRANSFORM_OT_resize";
+ Object *ob = ED_object_active_context((bContext *)C);
+
+ if (ob->wgroup == NULL) {
+ ob->wgroup = wgroup;
}
- return NULL;
+ WIDGETGROUP_manipulator_init(C, wgroup);
}
-/* return 0; nothing happened */
-int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
+static bool WIDGETGROUP_object_manipulator_poll(const bContext *C, wmManipulatorGroupType *wgrouptype)
{
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = sa->spacedata.first;
- ARegion *ar = CTX_wm_region(C);
- int constraint_axis[3] = {0, 0, 0};
- int val;
- const bool use_planar = RNA_boolean_get(op->ptr, "use_planar_constraint");
-
- if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return 0;
- if (!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return 0;
-
- /* Force orientation */
- RNA_enum_set(op->ptr, "constraint_orientation", v3d->twmode);
-
- // find the hotspots first test narrow hotspot
- val = manipulator_selectbuf(sa, ar, event->mval, 0.5f * (float)U.tw_hotspot);
- if (val) {
- wmOperatorType *ot;
- PointerRNA props_ptr;
- PropertyRNA *prop;
- const char *opname;
-
- // drawflags still global, for drawing call above
- drawflags = manipulator_selectbuf(sa, ar, event->mval, 0.2f * (float)U.tw_hotspot);
- if (drawflags == 0) drawflags = val;
-
- /* Planar constraint doesn't make sense for rotation, give other keymaps a chance */
- if ((drawflags & MAN_ROT_C) && use_planar) {
- return 0;
- }
-
- opname = manipulator_get_operator_name(drawflags);
- ot = WM_operatortype_find(opname, true);
- WM_operator_properties_create_ptr(&props_ptr, ot);
+ Object *ob = ED_object_active_context((bContext *)C);
- if (drawflags & MAN_TRANS_C) {
- switch (drawflags) {
- case MAN_TRANS_C:
- break;
- case MAN_TRANS_X:
- if (use_planar) {
- constraint_axis[1] = 1;
- constraint_axis[2] = 1;
- }
- else
- constraint_axis[0] = 1;
- break;
- case MAN_TRANS_Y:
- if (use_planar) {
- constraint_axis[0] = 1;
- constraint_axis[2] = 1;
- }
- else
- constraint_axis[1] = 1;
- break;
- case MAN_TRANS_Z:
- if (use_planar) {
- constraint_axis[0] = 1;
- constraint_axis[1] = 1;
- }
- else
- constraint_axis[2] = 1;
- break;
- }
- RNA_boolean_set_array(&props_ptr, "constraint_axis", constraint_axis);
- }
- else if (drawflags & MAN_SCALE_C) {
- switch (drawflags) {
- case MAN_SCALE_X:
- if (use_planar) {
- constraint_axis[1] = 1;
- constraint_axis[2] = 1;
- }
- else
- constraint_axis[0] = 1;
- break;
- case MAN_SCALE_Y:
- if (use_planar) {
- constraint_axis[0] = 1;
- constraint_axis[2] = 1;
- }
- else
- constraint_axis[1] = 1;
- break;
- case MAN_SCALE_Z:
- if (use_planar) {
- constraint_axis[0] = 1;
- constraint_axis[1] = 1;
- }
- else
- constraint_axis[2] = 1;
- break;
- }
- RNA_boolean_set_array(&props_ptr, "constraint_axis", constraint_axis);
- }
- else if (drawflags == MAN_ROT_T) {
- /* pass */
- }
- else if (drawflags & MAN_ROT_C) {
- switch (drawflags) {
- case MAN_ROT_X:
- constraint_axis[0] = 1;
- break;
- case MAN_ROT_Y:
- constraint_axis[1] = 1;
- break;
- case MAN_ROT_Z:
- constraint_axis[2] = 1;
- break;
- }
- RNA_boolean_set_array(&props_ptr, "constraint_axis", constraint_axis);
+ if (ED_operator_object_active((bContext *)C)) {
+ if (STREQ(wgrouptype->idname, ob->id.name)) {
+ return true;
}
+ }
+ return false;
+}
- /* pass operator properties on to transform operators */
- prop = RNA_struct_find_property(op->ptr, "use_accurate");
- if (RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(&props_ptr, prop, RNA_property_boolean_get(op->ptr, prop));
- }
- prop = RNA_struct_find_property(op->ptr, "release_confirm");
- if (RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(&props_ptr, prop, RNA_property_boolean_get(op->ptr, prop));
- }
- prop = RNA_struct_find_property(op->ptr, "constraint_orientation");
- if (RNA_property_is_set(op->ptr, prop)) {
- RNA_property_enum_set(&props_ptr, prop, RNA_property_enum_get(op->ptr, prop));
- }
+/* XXX should this really be in transform_manipulator.c? */
+void TRANSFORM_WGT_object(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Object Widgets";
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
- WM_operator_properties_free(&props_ptr);
- }
- /* after transform, restore drawflags */
- drawflags = 0xFFFF;
+ wgt->poll = WIDGETGROUP_object_manipulator_poll;
+ wgt->init = WIDGETGROUP_object_manipulator_init;
+ wgt->refresh = WIDGETGROUP_manipulator_refresh;
+ wgt->draw_prepare = WIDGETGROUP_manipulator_draw_prepare;
- return val;
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_IS_3D | WM_MANIPULATORGROUPTYPE_SCALE_3D);
}
-
+#endif
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c
index 3fb5059cae5..8236d9950a2 100644
--- a/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c
@@ -101,20 +101,19 @@ static void manipulator_arrow_get_final_pos(wmManipulator *manipulator, float r_
static void arrow_draw_geom(const ArrowManipulator *arrow, const bool select, const float color[4])
{
- /* USE_IMM for other arrow types */
- glColor4fv(color);
-
if (arrow->style & MANIPULATOR_ARROW_STYLE_CROSS) {
- glPushAttrib(GL_ENABLE_BIT);
- glDisable(GL_LIGHTING);
- glBegin(GL_LINES);
- glVertex2f(-1.0, 0.f);
- glVertex2f(1.0, 0.f);
- glVertex2f(0.f, -1.0);
- glVertex2f(0.f, 1.0);
- glEnd();
-
- glPopAttrib();
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ immUniformColor4fv(color);
+
+ immBegin(GL_LINES, 4);
+ immVertex2f(pos, -1.0, 0.f);
+ immVertex2f(pos, 1.0, 0.f);
+ immVertex2f(pos, 0.f, -1.0);
+ immVertex2f(pos, 0.f, 1.0);
+ immEnd();
+
+ immUnbindProgram();
}
else if (arrow->style & MANIPULATOR_ARROW_STYLE_CONE) {
const float unitx = arrow->aspect[0];
@@ -126,29 +125,48 @@ static void arrow_draw_geom(const ArrowManipulator *arrow, const bool select, co
{-unitx, unity, 0},
};
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4fv(color);
+
glLineWidth(arrow->manipulator.line_width);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, vec);
- glDrawArrays(GL_LINE_LOOP, 0, ARRAY_SIZE(vec));
- glDisableClientState(GL_VERTEX_ARRAY);
+
+ const int vec_size = ARRAY_SIZE(vec);
+ immBegin(PRIM_LINE_STRIP, vec_size);
+ for (int i = 0; i < vec_size; i++) {
+ immVertex3fv(pos, vec[i]);
+ }
+ immEnd();
+
glLineWidth(1.0);
+ immUnbindProgram();
+
}
else {
#ifdef USE_MANIPULATOR_CUSTOM_ARROWS
- wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_arrow, select);
+ wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_arrow, select, color);
#else
+ unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR);
+ immUniformColor4fv(color);
+
const float vec[2][3] = {
{0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, arrow->len},
};
glLineWidth(arrow->manipulator.line_width);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, vec);
- glDrawArrays(GL_LINE_STRIP, 0, ARRAY_SIZE(vec));
- glDisableClientState(GL_VERTEX_ARRAY);
- glLineWidth(1.0);
+ const int vec_size = ARRAY_SIZE(vec);
+ immBegin(PRIM_LINE_STRIP, vec_size);
+ for (int i = 0; i < vec_size; i++) {
+ immVertex3fv(pos, vec[i]);
+ }
+ immEnd();
+
+ glLineWidth(1.0);
/* *** draw arrow head *** */
@@ -163,7 +181,8 @@ static void arrow_draw_geom(const ArrowManipulator *arrow, const bool select, co
gpuScale3f(size, size, size);
/* draw cube */
- wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_cube, select);
+ immUnbindProgram();
+ wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_cube, select, color);
}
else {
const float len = 0.25f;
@@ -171,12 +190,8 @@ static void arrow_draw_geom(const ArrowManipulator *arrow, const bool select, co
const bool use_lighting = select == false && ((U.manipulator_flag & V3D_SHADED_MANIPULATORS) != 0);
/* translate to line end */
- unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", GL_FLOAT, 3, KEEP_FLOAT);
gpuTranslate3f(0.0f, 0.0f, arrow->len);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- immUniformColor4fv(color);
-
if (use_lighting) {
glShadeModel(GL_SMOOTH);
}
@@ -184,15 +199,15 @@ static void arrow_draw_geom(const ArrowManipulator *arrow, const bool select, co
imm_draw_circle_fill_3d(pos, 0.0, 0.0, width, 8);
imm_draw_cylinder_fill_3d(pos, width, 0.0, len, 8, 1);
- immUnbindProgram();
-
if (use_lighting) {
glShadeModel(GL_FLAT);
}
+ immUnbindProgram();
}
gpuPopMatrix();
+
#endif /* USE_MANIPULATOR_CUSTOM_ARROWS */
}
}
diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c
index e1f52a56e64..844de194845 100644
--- a/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c
+++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c
@@ -66,12 +66,6 @@
#include "manipulator_geometry.h"
#include "manipulator_library_intern.h"
-#define USE_IMM
-
-#ifndef USE_IMM
-#include <GL/glu.h>
-#endif
-
/* to use custom dials exported to geom_dial_manipulator.c */
// #define USE_MANIPULATOR_CUSTOM_DIAL
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
index b82a7469520..1917c473d94 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
@@ -39,7 +39,8 @@
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "GL/glew.h"
+#include "GPU_batch.h"
+#include "GPU_glew.h"
#include "MEM_guardedalloc.h"
@@ -57,53 +58,58 @@
/**
* Main draw call for ManipulatorGeomInfo data
*/
-void wm_manipulator_geometryinfo_draw(const ManipulatorGeomInfo *info, const bool select)
+void wm_manipulator_geometryinfo_draw(const ManipulatorGeomInfo *info, const bool select, const float color[4])
{
- GLuint buf[3];
- const bool use_lighting = !select && ((U.manipulator_flag & V3D_SHADED_MANIPULATORS) != 0);
+ /* TODO store the Batches inside the ManipulatorGeomInfo and updated it when geom changes
+ * So we don't need to re-created and discard it every time */
- if (use_lighting)
- glGenBuffers(3, buf);
- else
- glGenBuffers(2, buf);
+ const bool use_lighting = true || (!select && ((U.manipulator_flag & V3D_SHADED_MANIPULATORS) != 0));
+ VertexBuffer *vbo;
+ ElementList *el;
+ Batch *batch;
+ ElementListBuilder elb = {0};
- glEnableClientState(GL_VERTEX_ARRAY);
- glBindBuffer(GL_ARRAY_BUFFER, buf[0]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * info->nverts, info->verts, GL_STATIC_DRAW);
- glVertexPointer(3, GL_FLOAT, 0, NULL);
+ VertexFormat format = {0};
+ unsigned int pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ unsigned int nor_id;
if (use_lighting) {
- glEnableClientState(GL_NORMAL_ARRAY);
- glBindBuffer(GL_ARRAY_BUFFER, buf[2]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * info->nverts, info->normals, GL_STATIC_DRAW);
- glNormalPointer(GL_FLOAT, 0, NULL);
- glShadeModel(GL_SMOOTH);
+ nor_id = VertexFormat_add_attrib(&format, "nor", COMP_I16, 3, NORMALIZE_INT_TO_FLOAT);
}
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf[1]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * (3 * info->ntris), info->indices, GL_STATIC_DRAW);
+ /* Elements */
+ ElementListBuilder_init(&elb, GL_TRIANGLES, info->ntris, info->nverts);
+ for (int i = 0; i < info->ntris; ++i) {
+ const unsigned short *idx = &info->indices[i * 3];
+ add_triangle_vertices(&elb, idx[0], idx[1], idx[2]);
+ }
+ el = ElementList_build(&elb);
+
+ vbo = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(vbo, info->nverts);
+
+ VertexBuffer_fill_attrib(vbo, pos_id, info->verts);
+
+ if (use_lighting) {
+ /* Normals are expected to be smooth. */
+ VertexBuffer_fill_attrib(vbo, nor_id, info->normals);
+ }
+
+ batch = Batch_create(GL_TRIANGLES, vbo, el);
+ Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+
+ Batch_Uniform4fv(batch, "color", color);
glEnable(GL_CULL_FACE);
// glEnable(GL_DEPTH_TEST);
- glDrawElements(GL_TRIANGLES, info->ntris * 3, GL_UNSIGNED_SHORT, NULL);
+ Batch_draw(batch);
glDisable(GL_DEPTH_TEST);
// glDisable(GL_CULL_FACE);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- if (use_lighting) {
- glDisableClientState(GL_NORMAL_ARRAY);
- glShadeModel(GL_FLAT);
- glDeleteBuffers(3, buf);
- }
- else {
- glDeleteBuffers(2, buf);
- }
+ Batch_discard_all(batch);
}
/* Still unused */
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
index a1ea4bfc8ae..2acc72afc95 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
@@ -218,7 +218,7 @@ bool wm_manipulatormap_deselect_all(struct wmManipulatorMap *mmap, struct wmMani
/* -------------------------------------------------------------------- */
/* Manipulator drawing */
-void wm_manipulator_geometryinfo_draw(const struct ManipulatorGeomInfo *info, const bool select);
+void wm_manipulator_geometryinfo_draw(const struct ManipulatorGeomInfo *info, const bool select, const float color[4]);
#endif /* __WM_MANIPULATOR_INTERN_H__ */