diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-04-06 14:55:58 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-04-06 15:10:09 +0300 |
commit | d8f931c9b7db09f969a0a6379782103071e0e9f5 (patch) | |
tree | 730b1eeb0849ab39e722357630e01c7b07483102 /source/blender/windowmanager/manipulators | |
parent | 0feca278a48c494ca53dbd5f59985f9540a65401 (diff) |
Changes from custom-manipulators branch
Minor changes from custom-manipulators branch,
before larger changes are applied.
Diffstat (limited to 'source/blender/windowmanager/manipulators')
17 files changed, 3301 insertions, 39 deletions
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h index 099ad7fd851..c2d194c7c03 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h @@ -58,6 +58,9 @@ void WM_manipulator_delete( void WM_manipulator_set_property(struct wmManipulator *, int slot, struct PointerRNA *ptr, const char *propname); struct PointerRNA *WM_manipulator_set_operator(struct wmManipulator *, const char *opname); +void WM_manipulator_set_custom_handler( + struct wmManipulator *manipulator, + int (*handler)(struct bContext *, const struct wmEvent *, struct wmManipulator *, const int)); void WM_manipulator_set_func_select( struct wmManipulator *manipulator, void (*select)(struct bContext *, struct wmManipulator *, const int action)); /* wmManipulatorSelectFunc */ diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_library.h b/source/blender/windowmanager/manipulators/WM_manipulator_library.h new file mode 100644 index 00000000000..1e7106905e3 --- /dev/null +++ b/source/blender/windowmanager/manipulators/WM_manipulator_library.h @@ -0,0 +1,128 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/manipulators/WM_manipulator_library.h + * \ingroup wm + * + * \name Generic Manipulator Library + * + * Only included in WM_api.h and lower level files. + */ + + +#ifndef __WM_MANIPULATOR_LIBRARY_H__ +#define __WM_MANIPULATOR_LIBRARY_H__ + +struct wmManipulatorGroup; + + +/* -------------------------------------------------------------------- */ +/* 3D Arrow Manipulator */ + +enum { + MANIPULATOR_ARROW_STYLE_NORMAL = 1, + MANIPULATOR_ARROW_STYLE_NO_AXIS = (1 << 1), + MANIPULATOR_ARROW_STYLE_CROSS = (1 << 2), + MANIPULATOR_ARROW_STYLE_INVERTED = (1 << 3), /* inverted offset during interaction - if set it also sets constrained below */ + MANIPULATOR_ARROW_STYLE_CONSTRAINED = (1 << 4), /* clamp arrow interaction to property width */ + MANIPULATOR_ARROW_STYLE_BOX = (1 << 5), /* use a box for the arrowhead */ + MANIPULATOR_ARROW_STYLE_CONE = (1 << 6), +}; + +/* slots for properties */ +enum { + ARROW_SLOT_OFFSET_WORLD_SPACE = 0 +}; + +struct wmManipulator *MANIPULATOR_arrow_new(struct wmManipulatorGroup *mgroup, const char *name, const int style); +void MANIPULATOR_arrow_set_direction(struct wmManipulator *manipulator, const float direction[3]); +void MANIPULATOR_arrow_set_up_vector(struct wmManipulator *manipulator, const float direction[3]); +void MANIPULATOR_arrow_set_line_len(struct wmManipulator *manipulator, const float len); +void MANIPULATOR_arrow_set_ui_range(struct wmManipulator *manipulator, const float min, const float max); +void MANIPULATOR_arrow_set_range_fac(struct wmManipulator *manipulator, const float range_fac); +void MANIPULATOR_arrow_cone_set_aspect(struct wmManipulator *manipulator, const float aspect[2]); + + +/* -------------------------------------------------------------------- */ +/* 2D Arrow Manipulator */ + +struct wmManipulator *MANIPULATOR_arrow2d_new(struct wmManipulatorGroup *mgroup, const char *name); +void MANIPULATOR_arrow2d_set_angle(struct wmManipulator *manipulator, const float rot_fac); +void MANIPULATOR_arrow2d_set_line_len(struct wmManipulator *manipulator, const float len); + + +/* -------------------------------------------------------------------- */ +/* Cage Manipulator */ + +enum { + MANIPULATOR_RECT_TRANSFORM_STYLE_TRANSLATE = 1, /* Manipulator translates */ + MANIPULATOR_RECT_TRANSFORM_STYLE_ROTATE = (1 << 1), /* Manipulator rotates */ + MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE = (1 << 2), /* Manipulator scales */ + MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM = (1 << 3), /* Manipulator scales uniformly */ +}; + +enum { + RECT_TRANSFORM_SLOT_OFFSET = 0, + RECT_TRANSFORM_SLOT_SCALE = 1 +}; + +struct wmManipulator *MANIPULATOR_rect_transform_new( + struct wmManipulatorGroup *mgroup, const char *name, const int style); +void MANIPULATOR_rect_transform_set_dimensions( + struct wmManipulator *manipulator, const float width, const float height); + + +/* -------------------------------------------------------------------- */ +/* Dial Manipulator */ + +enum { + MANIPULATOR_DIAL_STYLE_RING = 0, + MANIPULATOR_DIAL_STYLE_RING_CLIPPED = 1, + MANIPULATOR_DIAL_STYLE_RING_FILLED = 2, +}; + +struct wmManipulator *MANIPULATOR_dial_new(struct wmManipulatorGroup *mgroup, const char *name, const int style); +void MANIPULATOR_dial_set_up_vector(struct wmManipulator *manipulator, const float direction[3]); + + +/* -------------------------------------------------------------------- */ +/* Facemap Manipulator */ + +struct wmManipulator *MANIPULATOR_facemap_new( + struct wmManipulatorGroup *mgroup, const char *name, const int style, + struct Object *ob, const int facemap); +struct bFaceMap *MANIPULATOR_facemap_get_fmap(struct wmManipulator *manipulator); + + +/* -------------------------------------------------------------------- */ +/* Primitive Manipulator */ + +enum { + MANIPULATOR_PRIMITIVE_STYLE_PLANE = 0, +}; + +struct wmManipulator *MANIPULATOR_primitive_new(struct wmManipulatorGroup *mgroup, const char *name, const int style); +void MANIPULATOR_primitive_set_direction(struct wmManipulator *manipulator, const float direction[3]); +void MANIPULATOR_primitive_set_up_vector(struct wmManipulator *manipulator, const float direction[3]); + +#endif /* __WM_MANIPULATOR_LIBRARY_H__ */ + diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h index 284a3e9bd22..8de33ca923e 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h @@ -71,21 +71,6 @@ enum { /* -------------------------------------------------------------------- */ /* wmManipulatorGroup */ -typedef struct wmManipulatorGroup { - struct wmManipulatorGroup *next, *prev; - - struct wmManipulatorGroupType *type; - ListBase manipulators; - - void *py_instance; /* python stores the class instance here */ - struct ReportList *reports; /* errors and warnings storage */ - - void *customdata; - void (*customdata_free)(void *); /* for freeing customdata from above */ - int flag; /* private */ - int pad; -} wmManipulatorGroup; - /* factory class for a manipulator-group type, gets called every time a new area is spawned */ typedef struct wmManipulatorGroupType { struct wmManipulatorGroupType *next, *prev; diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c new file mode 100644 index 00000000000..310aec9cbc1 --- /dev/null +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c @@ -0,0 +1,221 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2016 Blender Foundation. + * All rights reserved. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c + * \ingroup wm + * + * \name 2D Arrow Manipulator + * + * \brief Simple arrow manipulator which is dragged into a certain direction. + */ + +#include "BIF_gl.h" + +#include "BKE_context.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_rect.h" + +#include "DNA_manipulator_types.h" +#include "DNA_windowmanager_types.h" + +#include "ED_screen.h" + +#include "MEM_guardedalloc.h" + +#include "RNA_access.h" + +#include "WM_types.h" + +/* own includes */ +#include "WM_manipulator_types.h" +#include "wm_manipulator_wmapi.h" +#include "WM_manipulator_library.h" +#include "wm_manipulator_intern.h" +#include "manipulator_library_intern.h" + + +typedef struct ArrowManipulator2D { + struct wmManipulator manipulator; + + float angle; + float line_len; +} ArrowManipulator2D; + + +static void arrow2d_draw_geom(ArrowManipulator2D *arrow, const float origin[2]) +{ + const float size = 0.11f; + const float size_h = size / 2.0f; + const float len = arrow->line_len; + const float draw_line_ofs = (arrow->manipulator.line_width * 0.5f) / arrow->manipulator.scale; + + glPushMatrix(); + glTranslatef(UNPACK2(origin), 0.0f); + glScalef(arrow->manipulator.scale, arrow->manipulator.scale, 0.0f); + glRotatef(RAD2DEGF(arrow->angle), 0.0f, 0.0f, 1.0f); + /* local offset */ + glTranslatef(arrow->manipulator.offset[0] + draw_line_ofs, arrow->manipulator.offset[1], 0.0f); + + /* TODO get rid of immediate mode */ + glBegin(GL_LINES); + glVertex2f(0.0f, 0.0f); + glVertex2f(0.0f, len); + glEnd(); + glBegin(GL_TRIANGLES); + glVertex2f(size_h, len); + glVertex2f(-size_h, len); + glVertex2f(0.0f, len + size * 1.7f); + glEnd(); + + glPopMatrix(); +} + +static void manipulator_arrow2d_draw(const bContext *UNUSED(C), struct wmManipulator *manipulator) +{ + ArrowManipulator2D *arrow = (ArrowManipulator2D *)manipulator; + float col[4]; + + manipulator_color_get(manipulator, manipulator->state & WM_MANIPULATOR_HIGHLIGHT, col); + + glColor4fv(col); + glLineWidth(manipulator->line_width); + glEnable(GL_BLEND); + arrow2d_draw_geom(arrow, manipulator->origin); + glDisable(GL_BLEND); + + if (arrow->manipulator.interaction_data) { + ManipulatorInteraction *inter = arrow->manipulator.interaction_data; + + glColor4f(0.5f, 0.5f, 0.5f, 0.5f); + glEnable(GL_BLEND); + arrow2d_draw_geom(arrow, inter->init_origin); + glDisable(GL_BLEND); + } +} + +static int manipulator_arrow2d_invoke(bContext *UNUSED(C), const wmEvent *UNUSED(event), struct wmManipulator *manipulator) +{ + ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__); + + copy_v2_v2(inter->init_origin, manipulator->origin); + manipulator->interaction_data = inter; + + return OPERATOR_RUNNING_MODAL; +} + +static int manipulator_arrow2d_intersect(bContext *UNUSED(C), const wmEvent *event, struct wmManipulator *manipulator) +{ + ArrowManipulator2D *arrow = (ArrowManipulator2D *)manipulator; + const float mval[2] = {event->mval[0], event->mval[1]}; + const float line_len = arrow->line_len * manipulator->scale; + float mval_local[2]; + + copy_v2_v2(mval_local, mval); + sub_v2_v2(mval_local, manipulator->origin); + + float line[2][2]; + line[0][0] = line[0][1] = line[1][0] = 0.0f; + line[1][1] = line_len; + + /* rotate only if needed */ + if (arrow->angle != 0.0f) { + float rot_point[2]; + copy_v2_v2(rot_point, line[1]); + rotate_v2_v2fl(line[1], rot_point, arrow->angle); + } + + /* arrow line intersection check */ + float isect_1[2], isect_2[2]; + const int isect = isect_line_sphere_v2( + line[0], line[1], mval_local, MANIPULATOR_HOTSPOT + manipulator->line_width * 0.5f, + isect_1, isect_2); + + if (isect > 0) { + float line_ext[2][2]; /* extended line for segment check including hotspot */ + copy_v2_v2(line_ext[0], line[0]); + line_ext[1][0] = line[1][0] + MANIPULATOR_HOTSPOT * ((line[1][0] - line[0][0]) / line_len); + line_ext[1][1] = line[1][1] + MANIPULATOR_HOTSPOT * ((line[1][1] - line[0][1]) / line_len); + + const float lambda_1 = line_point_factor_v2(isect_1, line_ext[0], line_ext[1]); + if (isect == 1) { + return IN_RANGE_INCL(lambda_1, 0.0f, 1.0f); + } + else { + BLI_assert(isect == 2); + const float lambda_2 = line_point_factor_v2(isect_2, line_ext[0], line_ext[1]); + return IN_RANGE_INCL(lambda_1, 0.0f, 1.0f) && IN_RANGE_INCL(lambda_2, 0.0f, 1.0f); + } + } + + return 0; +} + +/* -------------------------------------------------------------------- */ +/** \name 2D Arrow Manipulator API + * + * \{ */ + +struct wmManipulator *MANIPULATOR_arrow2d_new(wmManipulatorGroup *mgroup, const char *name) +{ + ArrowManipulator2D *arrow = MEM_callocN(sizeof(ArrowManipulator2D), __func__); + + arrow->manipulator.draw = manipulator_arrow2d_draw; + arrow->manipulator.invoke = manipulator_arrow2d_invoke; +// arrow->manipulator.bind_to_prop = manipulator_arrow2d_bind_to_prop; +// arrow->manipulator.handler = manipulator_arrow2d_handler; + arrow->manipulator.intersect = manipulator_arrow2d_intersect; +// arrow->manipulator.exit = manipulator_arrow2d_exit; + arrow->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE; + + arrow->line_len = 1.0f; + + wm_manipulator_register(mgroup, &arrow->manipulator, name); + + return (struct wmManipulator *)arrow; +} + +void MANIPULATOR_arrow2d_set_angle(struct wmManipulator *manipulator, const float angle) +{ + ArrowManipulator2D *arrow = (ArrowManipulator2D *)manipulator; + arrow->angle = angle; +} + +void MANIPULATOR_arrow2d_set_line_len(struct wmManipulator *manipulator, const float len) +{ + ArrowManipulator2D *arrow = (ArrowManipulator2D *)manipulator; + arrow->line_len = len; +} + +/** \} */ /* Arrow Manipulator API */ + + +/* -------------------------------------------------------------------- */ + +void fix_linking_manipulator_arrow2d(void) +{ + (void)0; +} diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c new file mode 100644 index 00000000000..3fb5059cae5 --- /dev/null +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c @@ -0,0 +1,561 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2014 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c + * \ingroup wm + * + * \name Arrow Manipulator + * + * 3D Manipulator + * + * \brief Simple arrow manipulator which is dragged into a certain direction. + * The arrow head can have varying shapes, e.g. cone, box, etc. + */ + +#include "BIF_gl.h" + +#include "BKE_context.h" + +#include "BLI_math.h" + +#include "DNA_manipulator_types.h" +#include "DNA_view3d_types.h" + +#include "ED_view3d.h" +#include "ED_screen.h" + +#include "GPU_draw.h" +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" +#include "GPU_matrix.h" +#include "GPU_select.h" + +#include "MEM_guardedalloc.h" + +#include "RNA_access.h" + +#include "WM_types.h" +#include "WM_api.h" + +/* own includes */ +#include "wm_manipulator_wmapi.h" +#include "wm_manipulator_intern.h" +#include "manipulator_geometry.h" +#include "manipulator_library_intern.h" + +/* to use custom arrows exported to geom_arrow_manipulator.c */ +//#define USE_MANIPULATOR_CUSTOM_ARROWS + +/* ArrowManipulator->flag */ +enum { + ARROW_UP_VECTOR_SET = (1 << 0), + ARROW_CUSTOM_RANGE_SET = (1 << 1), +}; + +typedef struct ArrowManipulator { + wmManipulator manipulator; + + ManipulatorCommonData data; + + int style; + int flag; + + float len; /* arrow line length */ + float direction[3]; + float up[3]; + float aspect[2]; /* cone style only */ +} ArrowManipulator; + + +/* -------------------------------------------------------------------- */ + +static void manipulator_arrow_get_final_pos(wmManipulator *manipulator, float r_pos[3]) +{ + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + + mul_v3_v3fl(r_pos, arrow->direction, arrow->data.offset); + add_v3_v3(r_pos, arrow->manipulator.origin); +} + +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(); + } + else if (arrow->style & MANIPULATOR_ARROW_STYLE_CONE) { + const float unitx = arrow->aspect[0]; + const float unity = arrow->aspect[1]; + const float vec[4][3] = { + {-unitx, -unity, 0}, + { unitx, -unity, 0}, + { unitx, unity, 0}, + {-unitx, unity, 0}, + }; + + 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); + glLineWidth(1.0); + } + else { +#ifdef USE_MANIPULATOR_CUSTOM_ARROWS + wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_arrow, select); +#else + 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); + + + /* *** draw arrow head *** */ + + gpuPushMatrix(); + + if (arrow->style & MANIPULATOR_ARROW_STYLE_BOX) { + const float size = 0.05f; + + /* translate to line end with some extra offset so box starts exactly where line ends */ + gpuTranslate3f(0.0f, 0.0f, arrow->len + size); + /* scale down to box size */ + gpuScale3f(size, size, size); + + /* draw cube */ + wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_cube, select); + } + else { + const float len = 0.25f; + const float width = 0.06f; + 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); + } + + 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); + } + } + + gpuPopMatrix(); + +#endif /* USE_MANIPULATOR_CUSTOM_ARROWS */ + } +} + +static void arrow_draw_intern(ArrowManipulator *arrow, const bool select, const bool highlight) +{ + const float up[3] = {0.0f, 0.0f, 1.0f}; + float col[4]; + float rot[3][3]; + float mat[4][4]; + float final_pos[3]; + + manipulator_color_get(&arrow->manipulator, highlight, col); + manipulator_arrow_get_final_pos(&arrow->manipulator, final_pos); + + if (arrow->flag & ARROW_UP_VECTOR_SET) { + copy_v3_v3(rot[2], arrow->direction); + copy_v3_v3(rot[1], arrow->up); + cross_v3_v3v3(rot[0], arrow->up, arrow->direction); + } + else { + rotation_between_vecs_to_mat3(rot, up, arrow->direction); + } + copy_m4_m3(mat, rot); + copy_v3_v3(mat[3], final_pos); + mul_mat3_m4_fl(mat, arrow->manipulator.scale); + + gpuPushMatrix(); + gpuMultMatrix3D(mat); + + gpuTranslate3fv(arrow->manipulator.offset); + + glEnable(GL_BLEND); + arrow_draw_geom(arrow, select, col); + glDisable(GL_BLEND); + + gpuPopMatrix(); + + if (arrow->manipulator.interaction_data) { + ManipulatorInteraction *inter = arrow->manipulator.interaction_data; + + copy_m4_m3(mat, rot); + copy_v3_v3(mat[3], inter->init_origin); + mul_mat3_m4_fl(mat, inter->init_scale); + + gpuPushMatrix(); + gpuMultMatrix3D(mat); + gpuTranslate3fv(arrow->manipulator.offset); + + glEnable(GL_BLEND); + arrow_draw_geom(arrow, select, (const float [4]){0.5f, 0.5f, 0.5f, 0.5f}); + glDisable(GL_BLEND); + + gpuPopMatrix(); + } +} + +static void manipulator_arrow_render_3d_intersect( + const bContext *UNUSED(C), wmManipulator *manipulator, + int selectionbase) +{ + GPU_select_load_id(selectionbase); + arrow_draw_intern((ArrowManipulator *)manipulator, true, false); +} + +static void manipulator_arrow_draw(const bContext *UNUSED(C), wmManipulator *manipulator) +{ + arrow_draw_intern((ArrowManipulator *)manipulator, false, (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) != 0); +} + +/** + * Calculate arrow offset independent from prop min value, + * meaning the range will not be offset by min value first. + */ +#define USE_ABS_HANDLE_RANGE + +static int manipulator_arrow_handler(bContext *C, const wmEvent *event, wmManipulator *manipulator, const int flag) +{ + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + ManipulatorInteraction *inter = manipulator->interaction_data; + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + + float orig_origin[4]; + float viewvec[3], tangent[3], plane[3]; + float offset[4]; + float m_diff[2]; + float dir_2d[2], dir2d_final[2]; + float facdir = 1.0f; + bool use_vertical = false; + + + copy_v3_v3(orig_origin, inter->init_origin); + orig_origin[3] = 1.0f; + add_v3_v3v3(offset, orig_origin, arrow->direction); + offset[3] = 1.0f; + + /* calculate view vector */ + if (rv3d->is_persp) { + sub_v3_v3v3(viewvec, orig_origin, rv3d->viewinv[3]); + } + else { + copy_v3_v3(viewvec, rv3d->viewinv[2]); + } + normalize_v3(viewvec); + + /* first determine if view vector is really close to the direction. If it is, we use + * vertical movement to determine offset, just like transform system does */ + if (RAD2DEG(acos(dot_v3v3(viewvec, arrow->direction))) > 5.0f) { + /* multiply to projection space */ + mul_m4_v4(rv3d->persmat, orig_origin); + mul_v4_fl(orig_origin, 1.0f / orig_origin[3]); + mul_m4_v4(rv3d->persmat, offset); + mul_v4_fl(offset, 1.0f / offset[3]); + + sub_v2_v2v2(dir_2d, offset, orig_origin); + dir_2d[0] *= ar->winx; + dir_2d[1] *= ar->winy; + normalize_v2(dir_2d); + } + else { + dir_2d[0] = 0.0f; + dir_2d[1] = 1.0f; + use_vertical = true; + } + + /* find mouse difference */ + m_diff[0] = event->mval[0] - inter->init_mval[0]; + m_diff[1] = event->mval[1] - inter->init_mval[1]; + + /* project the displacement on the screen space arrow direction */ + project_v2_v2v2(dir2d_final, m_diff, dir_2d); + + float zfac = ED_view3d_calc_zfac(rv3d, orig_origin, NULL); + ED_view3d_win_to_delta(ar, dir2d_final, offset, zfac); + + add_v3_v3v3(orig_origin, offset, inter->init_origin); + + /* calculate view vector for the new position */ + if (rv3d->is_persp) { + sub_v3_v3v3(viewvec, orig_origin, rv3d->viewinv[3]); + } + else { + copy_v3_v3(viewvec, rv3d->viewinv[2]); + } + + normalize_v3(viewvec); + if (!use_vertical) { + float fac; + /* now find a plane parallel to the view vector so we can intersect with the arrow direction */ + cross_v3_v3v3(tangent, viewvec, offset); + cross_v3_v3v3(plane, tangent, viewvec); + fac = dot_v3v3(plane, offset) / dot_v3v3(arrow->direction, plane); + + facdir = (fac < 0.0) ? -1.0 : 1.0; + mul_v3_v3fl(offset, arrow->direction, fac); + } + else { + facdir = (m_diff[1] < 0.0) ? -1.0 : 1.0; + } + + + ManipulatorCommonData *data = &arrow->data; + const float ofs_new = facdir * len_v3(offset); + const int slot = ARROW_SLOT_OFFSET_WORLD_SPACE; + + /* set the property for the operator and call its modal function */ + if (manipulator->props[slot]) { + const bool constrained = arrow->style & MANIPULATOR_ARROW_STYLE_CONSTRAINED; + const bool inverted = arrow->style & MANIPULATOR_ARROW_STYLE_INVERTED; + const bool use_precision = flag & WM_MANIPULATOR_TWEAK_PRECISE; + float value = manipulator_value_from_offset(data, inter, ofs_new, constrained, inverted, use_precision); + + manipulator_property_value_set(C, manipulator, slot, value); + /* get clamped value */ + value = manipulator_property_value_get(manipulator, slot); + + data->offset = manipulator_offset_from_value(data, value, constrained, inverted); + } + else { + data->offset = ofs_new; + } + + /* tag the region for redraw */ + ED_region_tag_redraw(ar); + WM_event_add_mousemove(C); + + return OPERATOR_PASS_THROUGH; +} + + +static int manipulator_arrow_invoke(bContext *UNUSED(C), const wmEvent *event, wmManipulator *manipulator) +{ + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__); + PointerRNA ptr = manipulator->ptr[ARROW_SLOT_OFFSET_WORLD_SPACE]; + PropertyRNA *prop = manipulator->props[ARROW_SLOT_OFFSET_WORLD_SPACE]; + + if (prop) { + inter->init_value = RNA_property_float_get(&ptr, prop); + } + + inter->init_offset = arrow->data.offset; + + inter->init_mval[0] = event->mval[0]; + inter->init_mval[1] = event->mval[1]; + + inter->init_scale = manipulator->scale; + + manipulator_arrow_get_final_pos(manipulator, inter->init_origin); + + manipulator->interaction_data = inter; + + return OPERATOR_RUNNING_MODAL; +} + +static void manipulator_arrow_prop_data_update(wmManipulator *manipulator, const int slot) +{ + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + manipulator_property_data_update( + manipulator, &arrow->data, slot, + arrow->style & MANIPULATOR_ARROW_STYLE_CONSTRAINED, + arrow->style & MANIPULATOR_ARROW_STYLE_INVERTED); +} + +static void manipulator_arrow_exit(bContext *C, wmManipulator *manipulator, const bool cancel) +{ + if (!cancel) + return; + + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + ManipulatorCommonData *data = &arrow->data; + ManipulatorInteraction *inter = manipulator->interaction_data; + + manipulator_property_value_reset(C, manipulator, inter, ARROW_SLOT_OFFSET_WORLD_SPACE); + data->offset = inter->init_offset; +} + + +/* -------------------------------------------------------------------- */ +/** \name Arrow Manipulator API + * + * \{ */ + +wmManipulator *MANIPULATOR_arrow_new(wmManipulatorGroup *mgroup, const char *name, const int style) +{ + int real_style = style; + + /* inverted only makes sense in a constrained arrow */ + if (real_style & MANIPULATOR_ARROW_STYLE_INVERTED) { + real_style |= MANIPULATOR_ARROW_STYLE_CONSTRAINED; + } + + + ArrowManipulator *arrow = MEM_callocN(sizeof(ArrowManipulator), name); + const float dir_default[3] = {0.0f, 0.0f, 1.0f}; + + arrow->manipulator.draw = manipulator_arrow_draw; + arrow->manipulator.get_final_position = manipulator_arrow_get_final_pos; + arrow->manipulator.intersect = NULL; + arrow->manipulator.handler = manipulator_arrow_handler; + arrow->manipulator.invoke = manipulator_arrow_invoke; + arrow->manipulator.render_3d_intersection = manipulator_arrow_render_3d_intersect; + arrow->manipulator.prop_data_update = manipulator_arrow_prop_data_update; + arrow->manipulator.exit = manipulator_arrow_exit; + arrow->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE; + + arrow->style = real_style; + arrow->len = 1.0f; + arrow->data.range_fac = 1.0f; + copy_v3_v3(arrow->direction, dir_default); + + wm_manipulator_register(mgroup, &arrow->manipulator, name); + + return (wmManipulator *)arrow; +} + +/** + * Define direction the arrow will point towards + */ +void MANIPULATOR_arrow_set_direction(wmManipulator *manipulator, const float direction[3]) +{ + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + + copy_v3_v3(arrow->direction, direction); + normalize_v3(arrow->direction); +} + +/** + * Define up-direction of the arrow manipulator + */ +void MANIPULATOR_arrow_set_up_vector(wmManipulator *manipulator, const float direction[3]) +{ + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + + if (direction) { + copy_v3_v3(arrow->up, direction); + normalize_v3(arrow->up); + arrow->flag |= ARROW_UP_VECTOR_SET; + } + else { + arrow->flag &= ~ARROW_UP_VECTOR_SET; + } +} + +/** + * Define a custom arrow line length + */ +void MANIPULATOR_arrow_set_line_len(wmManipulator *manipulator, const float len) +{ + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + arrow->len = len; +} + +/** + * Define a custom property UI range + * + * \note Needs to be called before WM_manipulator_set_property! + */ +void MANIPULATOR_arrow_set_ui_range(wmManipulator *manipulator, const float min, const float max) +{ + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + + BLI_assert(min < max); + BLI_assert(!(arrow->manipulator.props[0] && "Make sure this function " + "is called before WM_manipulator_set_property")); + + arrow->data.range = max - min; + arrow->data.min = min; + arrow->data.flag |= MANIPULATOR_CUSTOM_RANGE_SET; +} + +/** + * Define a custom factor for arrow min/max distance + * + * \note Needs to be called before WM_manipulator_set_property! + */ +void MANIPULATOR_arrow_set_range_fac(wmManipulator *manipulator, const float range_fac) +{ + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + + BLI_assert(!(arrow->manipulator.props[0] && "Make sure this function " + "is called before WM_manipulator_set_property")); + + arrow->data.range_fac = range_fac; +} + +/** + * Define xy-aspect for arrow cone + */ +void MANIPULATOR_arrow_cone_set_aspect(wmManipulator *manipulator, const float aspect[2]) +{ + ArrowManipulator *arrow = (ArrowManipulator *)manipulator; + + copy_v2_v2(arrow->aspect, aspect); +} + +/** \} */ /* Arrow Manipulator API */ + + +/* -------------------------------------------------------------------- */ + +void fix_linking_manipulator_arrow(void) +{ + (void)0; +} diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c new file mode 100644 index 00000000000..a22ccfa7c83 --- /dev/null +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c @@ -0,0 +1,564 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2014 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c + * \ingroup wm + * + * \name Cage Manipulator + * + * 2D Manipulator + * + * \brief Rectangular manipulator acting as a 'cage' around its content. + * Interacting scales or translates the manipulator. + */ + +#include "BIF_gl.h" + +#include "BKE_context.h" + +#include "BLI_math.h" +#include "BLI_rect.h" + +#include "DNA_manipulator_types.h" + +#include "ED_screen.h" + +#include "MEM_guardedalloc.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +/* own includes */ +#include "wm_manipulator_wmapi.h" +#include "wm_manipulator_intern.h" + + +/* wmManipulator->highlighted_part */ +enum { + MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE = 1, + MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT = 2, + MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT = 3, + MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP = 4, + MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN = 5 +}; + +#define MANIPULATOR_RECT_MIN_WIDTH 15.0f +#define MANIPULATOR_RESIZER_WIDTH 20.0f + +typedef struct RectTransformManipulator { + wmManipulator manipulator; + float w, h; /* dimensions of manipulator */ + float rotation; /* rotation of the rectangle */ + float scale[2]; /* scaling for the manipulator for non-destructive editing. */ + int style; +} RectTransformManipulator; + + +/* -------------------------------------------------------------------- */ + +static void rect_transform_draw_corners(rctf *r, const float offsetx, const float offsety) +{ + glBegin(GL_LINES); + glVertex2f(r->xmin, r->ymin + offsety); + glVertex2f(r->xmin, r->ymin); + glVertex2f(r->xmin, r->ymin); + glVertex2f(r->xmin + offsetx, r->ymin); + + glVertex2f(r->xmax, r->ymin + offsety); + glVertex2f(r->xmax, r->ymin); + glVertex2f(r->xmax, r->ymin); + glVertex2f(r->xmax - offsetx, r->ymin); + + glVertex2f(r->xmax, r->ymax - offsety); + glVertex2f(r->xmax, r->ymax); + glVertex2f(r->xmax, r->ymax); + glVertex2f(r->xmax - offsetx, r->ymax); + + glVertex2f(r->xmin, r->ymax - offsety); + glVertex2f(r->xmin, r->ymax); + glVertex2f(r->xmin, r->ymax); + glVertex2f(r->xmin + offsetx, r->ymax); + glEnd(); +} + +static void rect_transform_draw_interaction( + const float col[4], const int highlighted, + const float half_w, const float half_h, + const float w, const float h, const float line_width) +{ + float verts[4][2]; + + switch (highlighted) { + case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT: + verts[0][0] = -half_w + w; + verts[0][1] = -half_h; + verts[1][0] = -half_w; + verts[1][1] = -half_h; + verts[2][0] = -half_w; + verts[2][1] = half_h; + verts[3][0] = -half_w + w; + verts[3][1] = half_h; + break; + + case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT: + verts[0][0] = half_w - w; + verts[0][1] = -half_h; + verts[1][0] = half_w; + verts[1][1] = -half_h; + verts[2][0] = half_w; + verts[2][1] = half_h; + verts[3][0] = half_w - w; + verts[3][1] = half_h; + break; + + case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN: + verts[0][0] = -half_w; + verts[0][1] = -half_h + h; + verts[1][0] = -half_w; + verts[1][1] = -half_h; + verts[2][0] = half_w; + verts[2][1] = -half_h; + verts[3][0] = half_w; + verts[3][1] = -half_h + h; + break; + + case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP: + verts[0][0] = -half_w; + verts[0][1] = half_h - h; + verts[1][0] = -half_w; + verts[1][1] = half_h; + verts[2][0] = half_w; + verts[2][1] = half_h; + verts[3][0] = half_w; + verts[3][1] = half_h - h; + break; + + default: + return; + } + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, verts); + glLineWidth(line_width + 3.0); + glColor3f(0.0, 0.0, 0.0); + glDrawArrays(GL_LINE_STRIP, 0, 3); + glLineWidth(line_width); + glColor3fv(col); + glDrawArrays(GL_LINE_STRIP, 0, 3); + glLineWidth(1.0); +} + +static void manipulator_rect_transform_draw(const bContext *UNUSED(C), wmManipulator *manipulator) +{ + RectTransformManipulator *cage = (RectTransformManipulator *)manipulator; + rctf r; + float w = cage->w; + float h = cage->h; + float aspx = 1.0f, aspy = 1.0f; + const float half_w = w / 2.0f; + const float half_h = h / 2.0f; + + r.xmin = -half_w; + r.ymin = -half_h; + r.xmax = half_w; + r.ymax = half_h; + + glPushMatrix(); + glTranslatef(manipulator->origin[0] + manipulator->offset[0], + manipulator->origin[1] + manipulator->offset[1], 0.0f); + if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) + glScalef(cage->scale[0], cage->scale[0], 1.0); + else + glScalef(cage->scale[0], cage->scale[1], 1.0); + + if (w > h) + aspx = h / w; + else + aspy = w / h; + w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / cage->scale[0]); + h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / + ((cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) ? cage->scale[0] : cage->scale[1])); + + /* corner manipulators */ + glColor3f(0.0, 0.0, 0.0); + glLineWidth(cage->manipulator.line_width + 3.0f); + + rect_transform_draw_corners(&r, w, h); + + /* corner manipulators */ + glColor3fv(manipulator->col); + glLineWidth(cage->manipulator.line_width); + rect_transform_draw_corners(&r, w, h); + + rect_transform_draw_interaction(manipulator->col, manipulator->highlighted_part, half_w, half_h, + w, h, cage->manipulator.line_width); + + glLineWidth(1.0); + glPopMatrix(); +} + +static int manipulator_rect_transform_get_cursor(wmManipulator *manipulator) +{ + switch (manipulator->highlighted_part) { + case MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE: + return BC_HANDCURSOR; + case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT: + case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT: + return CURSOR_X_MOVE; + case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN: + case MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP: + return CURSOR_Y_MOVE; + default: + return CURSOR_STD; + } +} + +static int manipulator_rect_transform_intersect(bContext *UNUSED(C), const wmEvent *event, wmManipulator *manipulator) +{ + RectTransformManipulator *cage = (RectTransformManipulator *)manipulator; + const float mouse[2] = {event->mval[0], event->mval[1]}; + //float matrot[2][2]; + float point_local[2]; + float w = cage->w; + float h = cage->h; + float half_w = w / 2.0f; + float half_h = h / 2.0f; + float aspx = 1.0f, aspy = 1.0f; + + /* rotate mouse in relation to the center and relocate it */ + sub_v2_v2v2(point_local, mouse, manipulator->origin); + point_local[0] -= manipulator->offset[0]; + point_local[1] -= manipulator->offset[1]; + //rotate_m2(matrot, -cage->transform.rotation); + + if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) + mul_v2_fl(point_local, 1.0f / cage->scale[0]); + else { + point_local[0] /= cage->scale[0]; + point_local[1] /= cage->scale[0]; + } + + if (cage->w > cage->h) + aspx = h / w; + else + aspy = w / h; + w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / cage->scale[0]); + h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / + ((cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) ? cage->scale[0] : cage->scale[1])); + + + rctf r; + + r.xmin = -half_w + w; + r.ymin = -half_h + h; + r.xmax = half_w - w; + r.ymax = half_h - h; + + bool isect = BLI_rctf_isect_pt_v(&r, point_local); + + if (isect) + return MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE; + + /* if manipulator does not have a scale intersection, don't do it */ + if (cage->style & (MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE | MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM)) { + r.xmin = -half_w; + r.ymin = -half_h; + r.xmax = -half_w + w; + r.ymax = half_h; + + isect = BLI_rctf_isect_pt_v(&r, point_local); + + if (isect) + return MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT; + + r.xmin = half_w - w; + r.ymin = -half_h; + r.xmax = half_w; + r.ymax = half_h; + + isect = BLI_rctf_isect_pt_v(&r, point_local); + + if (isect) + return MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT; + + r.xmin = -half_w; + r.ymin = -half_h; + r.xmax = half_w; + r.ymax = -half_h + h; + + isect = BLI_rctf_isect_pt_v(&r, point_local); + + if (isect) + return MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN; + + r.xmin = -half_w; + r.ymin = half_h - h; + r.xmax = half_w; + r.ymax = half_h; + + isect = BLI_rctf_isect_pt_v(&r, point_local); + + if (isect) + return MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP; + } + + return 0; +} + +typedef struct RectTransformInteraction { + float orig_mouse[2]; + float orig_offset[2]; + float orig_scale[2]; +} RectTransformInteraction; + +static bool manipulator_rect_transform_get_prop_value(wmManipulator *manipulator, const int slot, float *value) +{ + PropertyType type = RNA_property_type(manipulator->props[slot]); + + if (type != PROP_FLOAT) { + fprintf(stderr, "Rect Transform manipulator can only be bound to float properties"); + return false; + } + else { + if (slot == RECT_TRANSFORM_SLOT_OFFSET) { + if (RNA_property_array_length(&manipulator->ptr[slot], manipulator->props[slot]) != 2) { + fprintf(stderr, "Rect Transform manipulator offset not only be bound to array float property"); + return false; + } + RNA_property_float_get_array(&manipulator->ptr[slot], manipulator->props[slot], value); + } + else if (slot == RECT_TRANSFORM_SLOT_SCALE) { + RectTransformManipulator *cage = (RectTransformManipulator *)manipulator; + if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) { + *value = RNA_property_float_get(&manipulator->ptr[slot], manipulator->props[slot]); + } + else { + if (RNA_property_array_length(&manipulator->ptr[slot], manipulator->props[slot]) != 2) { + fprintf(stderr, "Rect Transform manipulator scale not only be bound to array float property"); + return false; + } + RNA_property_float_get_array(&manipulator->ptr[slot], manipulator->props[slot], value); + } + } + } + + return true; +} + +static int manipulator_rect_transform_invoke(bContext *UNUSED(C), const wmEvent *event, wmManipulator *manipulator) +{ + RectTransformManipulator *cage = (RectTransformManipulator *)manipulator; + RectTransformInteraction *data = MEM_callocN(sizeof(RectTransformInteraction), "cage_interaction"); + + copy_v2_v2(data->orig_offset, manipulator->offset); + copy_v2_v2(data->orig_scale, cage->scale); + + data->orig_mouse[0] = event->mval[0]; + data->orig_mouse[1] = event->mval[1]; + + manipulator->interaction_data = data; + + return OPERATOR_RUNNING_MODAL; +} + +static int manipulator_rect_transform_handler( + bContext *C, const wmEvent *event, wmManipulator *manipulator, + const int UNUSED(flag)) +{ + RectTransformManipulator *cage = (RectTransformManipulator *)manipulator; + RectTransformInteraction *data = manipulator->interaction_data; + /* needed here as well in case clamping occurs */ + const float orig_ofx = manipulator->offset[0], orig_ofy = manipulator->offset[1]; + + const float valuex = (event->mval[0] - data->orig_mouse[0]); + const float valuey = (event->mval[1] - data->orig_mouse[1]); + + + if (manipulator->highlighted_part == MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE) { + manipulator->offset[0] = data->orig_offset[0] + valuex; + manipulator->offset[1] = data->orig_offset[1] + valuey; + } + else if (manipulator->highlighted_part == MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT) { + manipulator->offset[0] = data->orig_offset[0] + valuex / 2.0; + cage->scale[0] = (cage->w * data->orig_scale[0] - valuex) / cage->w; + } + else if (manipulator->highlighted_part == MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT) { + manipulator->offset[0] = data->orig_offset[0] + valuex / 2.0; + cage->scale[0] = (cage->w * data->orig_scale[0] + valuex) / cage->w; + } + else if (manipulator->highlighted_part == MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN) { + manipulator->offset[1] = data->orig_offset[1] + valuey / 2.0; + + if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) { + cage->scale[0] = (cage->h * data->orig_scale[0] - valuey) / cage->h; + } + else { + cage->scale[1] = (cage->h * data->orig_scale[1] - valuey) / cage->h; + } + } + else if (manipulator->highlighted_part == MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP) { + manipulator->offset[1] = data->orig_offset[1] + valuey / 2.0; + + if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) { + cage->scale[0] = (cage->h * data->orig_scale[0] + valuey) / cage->h; + } + else { + cage->scale[1] = (cage->h * data->orig_scale[1] + valuey) / cage->h; + } + } + + /* clamping - make sure manipulator is at least 5 pixels wide */ + if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) { + if (cage->scale[0] < MANIPULATOR_RECT_MIN_WIDTH / cage->h || + cage->scale[0] < MANIPULATOR_RECT_MIN_WIDTH / cage->w) + { + cage->scale[0] = max_ff(MANIPULATOR_RECT_MIN_WIDTH / cage->h, MANIPULATOR_RECT_MIN_WIDTH / cage->w); + manipulator->offset[0] = orig_ofx; + manipulator->offset[1] = orig_ofy; + } + } + else { + if (cage->scale[0] < MANIPULATOR_RECT_MIN_WIDTH / cage->w) { + cage->scale[0] = MANIPULATOR_RECT_MIN_WIDTH / cage->w; + manipulator->offset[0] = orig_ofx; + } + if (cage->scale[1] < MANIPULATOR_RECT_MIN_WIDTH / cage->h) { + cage->scale[1] = MANIPULATOR_RECT_MIN_WIDTH / cage->h; + manipulator->offset[1] = orig_ofy; + } + } + + if (manipulator->props[RECT_TRANSFORM_SLOT_OFFSET]) { + PointerRNA ptr = manipulator->ptr[RECT_TRANSFORM_SLOT_OFFSET]; + PropertyRNA *prop = manipulator->props[RECT_TRANSFORM_SLOT_OFFSET]; + + RNA_property_float_set_array(&ptr, prop, manipulator->offset); + RNA_property_update(C, &ptr, prop); + } + + if (manipulator->props[RECT_TRANSFORM_SLOT_SCALE]) { + PointerRNA ptr = manipulator->ptr[RECT_TRANSFORM_SLOT_SCALE]; + PropertyRNA *prop = manipulator->props[RECT_TRANSFORM_SLOT_SCALE]; + + if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) { + RNA_property_float_set(&ptr, prop, cage->scale[0]); + } + else { + RNA_property_float_set_array(&ptr, prop, cage->scale); + } + RNA_property_update(C, &ptr, prop); + } + + /* tag the region for redraw */ + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_PASS_THROUGH; +} + +static void manipulator_rect_transform_prop_data_update(wmManipulator *manipulator, const int slot) +{ + RectTransformManipulator *cage = (RectTransformManipulator *)manipulator; + + if (slot == RECT_TRANSFORM_SLOT_OFFSET) + manipulator_rect_transform_get_prop_value(manipulator, RECT_TRANSFORM_SLOT_OFFSET, manipulator->offset); + if (slot == RECT_TRANSFORM_SLOT_SCALE) + manipulator_rect_transform_get_prop_value(manipulator, RECT_TRANSFORM_SLOT_SCALE, cage->scale); +} + +static void manipulator_rect_transform_exit(bContext *C, wmManipulator *manipulator, const bool cancel) +{ + RectTransformManipulator *cage = (RectTransformManipulator *)manipulator; + RectTransformInteraction *data = manipulator->interaction_data; + + if (!cancel) + return; + + /* reset properties */ + if (manipulator->props[RECT_TRANSFORM_SLOT_OFFSET]) { + PointerRNA ptr = manipulator->ptr[RECT_TRANSFORM_SLOT_OFFSET]; + PropertyRNA *prop = manipulator->props[RECT_TRANSFORM_SLOT_OFFSET]; + + RNA_property_float_set_array(&ptr, prop, data->orig_offset); + RNA_property_update(C, &ptr, prop); + } + if (manipulator->props[RECT_TRANSFORM_SLOT_SCALE]) { + PointerRNA ptr = manipulator->ptr[RECT_TRANSFORM_SLOT_SCALE]; + PropertyRNA *prop = manipulator->props[RECT_TRANSFORM_SLOT_SCALE]; + + if (cage->style & MANIPULATOR_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) { + RNA_property_float_set(&ptr, prop, data->orig_scale[0]); + } + else { + RNA_property_float_set_array(&ptr, prop, data->orig_scale); + } + RNA_property_update(C, &ptr, prop); + } +} + + +/* -------------------------------------------------------------------- */ +/** \name Cage Manipulator API + * + * \{ */ + +wmManipulator *MANIPULATOR_rect_transform_new(wmManipulatorGroup *mgroup, const char *name, const int style) +{ + RectTransformManipulator *cage = MEM_callocN(sizeof(RectTransformManipulator), name); + + cage->manipulator.draw = manipulator_rect_transform_draw; + cage->manipulator.invoke = manipulator_rect_transform_invoke; + cage->manipulator.prop_data_update = manipulator_rect_transform_prop_data_update; + cage->manipulator.handler = manipulator_rect_transform_handler; + cage->manipulator.intersect = manipulator_rect_transform_intersect; + cage->manipulator.exit = manipulator_rect_transform_exit; + cage->manipulator.get_cursor = manipulator_rect_transform_get_cursor; + cage->manipulator.max_prop = 2; + cage->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE; + cage->scale[0] = cage->scale[1] = 1.0f; + cage->style = style; + + wm_manipulator_register(mgroup, &cage->manipulator, name); + + return (wmManipulator *)cage; +} + +void MANIPULATOR_rect_transform_set_dimensions(wmManipulator *manipulator, const float width, const float height) +{ + RectTransformManipulator *cage = (RectTransformManipulator *)manipulator; + cage->w = width; + cage->h = height; +} + +/** \} */ // Cage Manipulator API + + +/* -------------------------------------------------------------------- */ + +void fix_linking_manipulator_cage(void) +{ + (void)0; +} diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c new file mode 100644 index 00000000000..e1f52a56e64 --- /dev/null +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c @@ -0,0 +1,381 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2014 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c + * \ingroup wm + * + * \name Dial Manipulator + * + * 3D Manipulator + * + * \brief Circle shaped manipulator for circular interaction. + * Currently no own handling, use with operator only. + */ + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "BKE_context.h" + +#include "BLI_math.h" + +#include "DNA_manipulator_types.h" + +#include "ED_screen.h" +#include "ED_view3d.h" + +#include "GPU_select.h" + +#include "GPU_matrix.h" + +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" + +#include "MEM_guardedalloc.h" + +#include "WM_api.h" +#include "WM_types.h" + +/* own includes */ +#include "WM_manipulator_types.h" +#include "WM_manipulator_library.h" +#include "wm_manipulator_wmapi.h" +#include "wm_manipulator_intern.h" +#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 + +typedef struct DialManipulator { + wmManipulator manipulator; + int style; + float direction[3]; +} DialManipulator; + +typedef struct DialInteraction { + float init_mval[2]; + + /* cache the last angle to detect rotations bigger than -/+ PI */ + float last_angle; + /* number of full rotations */ + int rotations; +} DialInteraction; + +#define DIAL_WIDTH 1.0f +#define DIAL_RESOLUTION 32 + +/* -------------------------------------------------------------------- */ + +static void dial_geom_draw( + const DialManipulator *dial, const float col[4], const bool select, + float axis_modal_mat[4][4], float clip_plane[4]) +{ +#ifdef USE_MANIPULATOR_CUSTOM_DIAL + UNUSED_VARS(dial, col, axis_modal_mat, clip_plane); + wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_dial, select); +#else + const bool filled = (dial->style == MANIPULATOR_DIAL_STYLE_RING_FILLED); + + glLineWidth(dial->manipulator.line_width); + + VertexFormat *format = immVertexFormat(); + unsigned int pos = VertexFormat_add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); + + if (clip_plane) { + immBindBuiltinProgram(GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR); + float clip_plane_f[4] = {clip_plane[0], clip_plane[1], clip_plane[2], clip_plane[3]}; + immUniform4fv("ClipPlane", clip_plane_f); + immUniformMatrix4fv("ModelMatrix", axis_modal_mat); + } + else { + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + } + + immUniformColor4fv(col); + + if (filled) { + imm_draw_circle_fill(pos, 0, 0, 1.0, DIAL_RESOLUTION); + } + else { + imm_draw_circle_wire(pos, 0, 0, 1.0, DIAL_RESOLUTION); + } + + immUnbindProgram(); + + UNUSED_VARS(select); +#endif +} + +/** + * Draws a line from (0, 0, 0) to \a co_outer, at \a angle. + */ +static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[3], const float col[4]) +{ + glLineWidth(1.0f); + + gpuPushMatrix(); + gpuRotate3f(RAD2DEGF(angle), 0.0f, 0.0f, -1.0f); + + unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", GL_FLOAT, 3, KEEP_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + + immUniformColor4fv(col); + + immBegin(PRIM_LINE_STRIP, 2); + immVertex3f(pos, 0.0f, 0.0f, 0.0f); + immVertex3fv(pos, co_outer); + immEnd(); + + immUnbindProgram(); + + gpuPopMatrix(); +} + +static void dial_ghostarc_draw( + const DialManipulator *dial, const float angle_ofs, const float angle_delta, const float color[4]) +{ + const float width_inner = DIAL_WIDTH - dial->manipulator.line_width * 0.5f / U.manipulator_scale; + + VertexFormat *format = immVertexFormat(); + unsigned int pos = VertexFormat_add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + immUniformColor4fv(color); + imm_draw_disk_partial_fill( + pos, 0, 0, 0.0, width_inner, DIAL_RESOLUTION, RAD2DEGF(angle_ofs), RAD2DEGF(angle_delta)); + immUnbindProgram(); +} + +static void dial_ghostarc_get_angles( + const DialManipulator *dial, const wmEvent *event, const ARegion *ar, + float mat[4][4], const float co_outer[3], + float *r_start, float *r_delta) +{ + DialInteraction *inter = dial->manipulator.interaction_data; + const RegionView3D *rv3d = ar->regiondata; + const float mval[2] = {event->x - ar->winrct.xmin, event->y - ar->winrct.ymin}; + bool inv = false; + + /* we might need to invert the direction of the angles */ + float view_vec[3], axis_vec[3]; + ED_view3d_global_to_vector(rv3d, rv3d->twmat[3], view_vec); + normalize_v3_v3(axis_vec, dial->direction); + if (dot_v3v3(view_vec, axis_vec) < 0.0f) { + inv = true; + } + + float co[3], origin2d[2], co2d[2]; + mul_v3_project_m4_v3(co, mat, co_outer); + /* project 3d coordinats to 2d viewplane */ + ED_view3d_project_float_global(ar, dial->manipulator.origin, origin2d, V3D_PROJ_TEST_NOP); + ED_view3d_project_float_global(ar, co, co2d, V3D_PROJ_TEST_NOP); + + /* convert to manipulator relative space */ + float rel_initmval[2], rel_mval[2], rel_co[2]; + sub_v2_v2v2(rel_initmval, inter->init_mval, origin2d); + sub_v2_v2v2(rel_mval, mval, origin2d); + sub_v2_v2v2(rel_co, co2d, origin2d); + + /* return angles */ + const float start = angle_signed_v2v2(rel_co, rel_initmval) * (inv ? -1 : 1); + const float delta = angle_signed_v2v2(rel_initmval, rel_mval) * (inv ? -1 : 1); + + /* Change of sign, we passed the 180 degree threshold. This means we need to add a turn + * to distinguish between transition from 0 to -1 and -PI to +PI, use comparison with PI/2. + * Logic taken from BLI_dial_angle */ + if ((delta * inter->last_angle < 0.0f) && + (fabsf(inter->last_angle) > (float)M_PI_2)) + { + if (inter->last_angle < 0.0f) + inter->rotations--; + else + inter->rotations++; + } + inter->last_angle = delta; + + *r_start = start; + *r_delta = fmod(delta + 2.0f * (float)M_PI * inter->rotations, 2 * (float)M_PI); +} + +static void dial_draw_intern( + const bContext *C, DialManipulator *dial, + const bool select, const bool highlight, float clip_plane[4]) +{ + float rot[3][3]; + float mat[4][4]; + const float up[3] = {0.0f, 0.0f, 1.0f}; + float col[4]; + + BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D); + + manipulator_color_get(&dial->manipulator, highlight, col); + + rotation_between_vecs_to_mat3(rot, up, dial->direction); + copy_m4_m3(mat, rot); + copy_v3_v3(mat[3], dial->manipulator.origin); + mul_mat3_m4_fl(mat, dial->manipulator.scale); + + gpuPushMatrix(); + gpuMultMatrix3D(mat); + gpuTranslate3fv(dial->manipulator.offset); + + /* draw rotation indicator arc first */ + if ((dial->manipulator.flag & WM_MANIPULATOR_DRAW_VALUE) && (dial->manipulator.state & WM_MANIPULATOR_ACTIVE)) { + wmWindow *win = CTX_wm_window(C); + const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; /* coordinate at which the arc drawing will be started */ + float angle_ofs, angle_delta; + + dial_ghostarc_get_angles(dial, win->eventstate, CTX_wm_region(C), mat, co_outer, &angle_ofs, &angle_delta); + /* draw! */ + dial_ghostarc_draw(dial, angle_ofs, angle_delta, (const float [4]){0.8f, 0.8f, 0.8f, 0.4f}); + + dial_ghostarc_draw_helpline(angle_ofs, co_outer, col); /* starting position */ + dial_ghostarc_draw_helpline(angle_ofs + angle_delta, co_outer, col); /* starting position + current value */ + } + + /* draw actual dial manipulator */ + dial_geom_draw(dial, col, select, mat, clip_plane); + + gpuPopMatrix(); +} + +static void manipulator_dial_render_3d_intersect(const bContext *C, wmManipulator *manipulator, int selectionbase) +{ + DialManipulator *dial = (DialManipulator *)manipulator; + float clip_plane_buf[4]; + float *clip_plane = (dial->style == MANIPULATOR_DIAL_STYLE_RING_CLIPPED) ? clip_plane_buf : NULL; + + /* enable clipping if needed */ + if (clip_plane) { + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + + copy_v3_v3(clip_plane, rv3d->viewinv[2]); + clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], manipulator->origin); + glEnable(GL_CLIP_DISTANCE0); + } + + GPU_select_load_id(selectionbase); + dial_draw_intern(C, dial, true, false, clip_plane); + + if (clip_plane) { + glDisable(GL_CLIP_DISTANCE0); + } +} + +static void manipulator_dial_draw(const bContext *C, wmManipulator *manipulator) +{ + DialManipulator *dial = (DialManipulator *)manipulator; + const bool active = manipulator->state & WM_MANIPULATOR_ACTIVE; + const bool highlight = (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) != 0; + float clip_plane_buf[4]; + float *clip_plane = (!active && dial->style == MANIPULATOR_DIAL_STYLE_RING_CLIPPED) ? clip_plane_buf : NULL; + + /* enable clipping if needed */ + if (clip_plane) { + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + + copy_v3_v3(clip_plane, rv3d->viewinv[2]); + clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], manipulator->origin); + clip_plane[3] -= 0.02 * dial->manipulator.scale; + + glEnable(GL_CLIP_DISTANCE0); + } + + glEnable(GL_BLEND); + dial_draw_intern(C, dial, false, highlight, clip_plane); + glDisable(GL_BLEND); + + if (clip_plane) { + glDisable(GL_CLIP_DISTANCE0); + } +} + +static int manipulator_dial_invoke(bContext *UNUSED(C), const wmEvent *event, wmManipulator *manipulator) +{ + DialInteraction *inter = MEM_callocN(sizeof(DialInteraction), __func__); + + inter->init_mval[0] = event->mval[0]; + inter->init_mval[1] = event->mval[1]; + + manipulator->interaction_data = inter; + + return OPERATOR_RUNNING_MODAL; +} + + +/* -------------------------------------------------------------------- */ +/** \name Dial Manipulator API + * + * \{ */ + +wmManipulator *MANIPULATOR_dial_new(wmManipulatorGroup *mgroup, const char *name, const int style) +{ + DialManipulator *dial = MEM_callocN(sizeof(DialManipulator), name); + const float dir_default[3] = {0.0f, 0.0f, 1.0f}; + + dial->manipulator.draw = manipulator_dial_draw; + dial->manipulator.intersect = NULL; + dial->manipulator.render_3d_intersection = manipulator_dial_render_3d_intersect; + dial->manipulator.invoke = manipulator_dial_invoke; + + dial->style = style; + + /* defaults */ + copy_v3_v3(dial->direction, dir_default); + + wm_manipulator_register(mgroup, &dial->manipulator, name); + + return (wmManipulator *)dial; +} + +/** + * Define up-direction of the dial manipulator + */ +void MANIPULATOR_dial_set_up_vector(wmManipulator *manipulator, const float direction[3]) +{ + DialManipulator *dial = (DialManipulator *)manipulator; + + copy_v3_v3(dial->direction, direction); + normalize_v3(dial->direction); +} + +/** \} */ // Dial Manipulator API + + +/* -------------------------------------------------------------------- */ + +void fix_linking_manipulator_dial(void) +{ + (void)0; +} diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_arrow_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_arrow_manipulator.c new file mode 100644 index 00000000000..0f874e588bc --- /dev/null +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_arrow_manipulator.c @@ -0,0 +1,141 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2016 Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/manipulators/intern/manipulator_library/geom_arrow_manipulator.c + * \ingroup wm + */ + +#include "manipulator_geometry.h" + +static float verts[][3] = { + {-0.000000, 0.012320, 0.000000}, + {-0.000000, 0.012320, 0.974306}, + {0.008711, 0.008711, 0.000000}, + {0.008711, 0.008711, 0.974306}, + {0.012320, -0.000000, 0.000000}, + {0.012320, -0.000000, 0.974306}, + {0.008711, -0.008711, 0.000000}, + {0.008711, -0.008711, 0.974306}, + {-0.000000, -0.012320, 0.000000}, + {-0.000000, -0.012320, 0.974306}, + {-0.008711, -0.008711, 0.000000}, + {-0.008711, -0.008711, 0.974306}, + {-0.012320, 0.000000, 0.000000}, + {-0.012320, 0.000000, 0.974306}, + {-0.008711, 0.008711, 0.000000}, + {-0.008711, 0.008711, 0.974306}, + {0.000000, 0.072555, 0.974306}, + {0.051304, 0.051304, 0.974306}, + {0.072555, -0.000000, 0.974306}, + {0.051304, -0.051304, 0.974306}, + {-0.000000, -0.072555, 0.974306}, + {-0.051304, -0.051304, 0.974306}, + {-0.072555, 0.000000, 0.974306}, + {-0.051304, 0.051304, 0.974306}, + {0.000000, -0.000000, 1.268098}, +}; + +static float normals[][3] = { + {0.000000, 0.776360, -0.630238}, + {0.000000, 0.594348, -0.804163}, + {0.548967, 0.548967, -0.630238}, + {0.420270, 0.420270, -0.804163}, + {0.776360, 0.000000, -0.630238}, + {0.594378, 0.000000, -0.804163}, + {0.548967, -0.548967, -0.630238}, + {0.420270, -0.420270, -0.804163}, + {0.000000, -0.776360, -0.630238}, + {0.000000, -0.594378, -0.804163}, + {-0.548967, -0.548967, -0.630238}, + {-0.420270, -0.420270, -0.804163}, + {-0.776360, 0.000000, -0.630238}, + {-0.594378, 0.000000, -0.804163}, + {-0.548967, 0.548967, -0.630238}, + {-0.420270, 0.420270, -0.804163}, + {0.000000, 0.843226, -0.537492}, + {0.596271, 0.596271, -0.537492}, + {0.843226, 0.000000, -0.537492}, + {0.596271, -0.596271, -0.537492}, + {0.000000, -0.843226, -0.537492}, + {-0.596271, -0.596271, -0.537492}, + {-0.843226, 0.000000, -0.537492}, + {-0.596271, 0.596271, -0.537492}, + {0.000000, 0.000000, 1.000000}, +}; + +static unsigned short indices[] = { + 1, 3, 2, + 3, 5, 4, + 5, 7, 6, + 7, 9, 8, + 9, 11, 10, + 11, 13, 12, + 5, 18, 19, + 15, 1, 0, + 13, 15, 14, + 6, 10, 14, + 11, 21, 22, + 7, 19, 20, + 13, 22, 23, + 3, 17, 18, + 9, 20, 21, + 15, 23, 16, + 1, 16, 17, + 23, 22, 24, + 21, 20, 24, + 19, 18, 24, + 17, 16, 24, + 16, 23, 24, + 22, 21, 24, + 20, 19, 24, + 18, 17, 24, + 0, 1, 2, + 2, 3, 4, + 4, 5, 6, + 6, 7, 8, + 8, 9, 10, + 10, 11, 12, + 7, 5, 19, + 14, 15, 0, + 12, 13, 14, + 14, 0, 2, + 2, 4, 6, + 6, 8, 10, + 10, 12, 14, + 14, 2, 6, + 13, 11, 22, + 9, 7, 20, + 15, 13, 23, + 5, 3, 18, + 11, 9, 21, + 1, 15, 16, + 3, 1, 17, +}; + +ManipulatorGeomInfo wm_manipulator_geom_data_arrow = { + .nverts = 25, + .ntris = 46, + .verts = verts, + .normals = normals, + .indices = indices, +}; diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_cube_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_cube_manipulator.c new file mode 100644 index 00000000000..d0600705258 --- /dev/null +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_cube_manipulator.c @@ -0,0 +1,75 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2016 Blender Foundation. + * All rights reserved. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/manipulators/intern/manipulator_library/geom_cube_manipulator.c + * \ingroup wm + */ + +#include "manipulator_geometry.h" + +static const float verts[][3] = { + {1.000000, 1.000000, -1.000000}, + {1.000000, -1.000000, -1.000000}, + {-1.000000, -1.000000, -1.000000}, + {-1.000000, 1.000000, -1.000000}, + {1.000000, 1.000000, 1.000000}, + {0.999999, -1.000001, 1.000000}, + {-1.000000, -1.000000, 1.000000}, + {-1.000000, 1.000000, 1.000000}, +}; + +static const float normals[][3] = { + {0.577349, 0.577349, -0.577349}, + {0.577349, -0.577349, -0.577349}, + {-0.577349, -0.577349, -0.577349}, + {-0.577349, 0.577349, -0.577349}, + {0.577349, 0.577349, 0.577349}, + {0.577349, -0.577349, 0.577349}, + {-0.577349, -0.577349, 0.577349}, + {-0.577349, 0.577349, 0.577349}, +}; + +static const unsigned short indices[] = { + 1, 2, 3, + 7, 6, 5, + 4, 5, 1, + 5, 6, 2, + 2, 6, 7, + 0, 3, 7, + 0, 1, 3, + 4, 7, 5, + 0, 4, 1, + 1, 5, 2, + 3, 2, 7, + 4, 0, 7, +}; + +ManipulatorGeomInfo wm_manipulator_geom_data_cube = { + .nverts = 8, + .ntris = 12, + .verts = verts, + .normals = normals, + .indices = indices, +}; diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_dial_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_dial_manipulator.c new file mode 100644 index 00000000000..7f2edbcf60e --- /dev/null +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/geom_dial_manipulator.c @@ -0,0 +1,813 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2016 Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/manipulators/intern/manipulator_library/geom_dial_manipulator.c + * \ingroup wm + */ + +#include "manipulator_geometry.h" + +static const float verts[][3] = { + {1.034000, 0.000000, 0.000000}, + {1.017000, 0.000000, 0.029445}, + {0.983000, 0.000000, 0.029445}, + {0.966000, 0.000000, 0.000000}, + {0.983000, 0.000000, -0.029445}, + {1.017000, 0.000000, -0.029445}, + {1.014132, 0.201723, 0.000000}, + {0.997459, 0.198407, 0.029445}, + {0.964112, 0.191774, 0.029445}, + {0.947439, 0.188457, 0.000000}, + {0.964112, 0.191774, -0.029445}, + {0.997459, 0.198407, -0.029445}, + {0.955292, 0.395695, 0.000000}, + {0.939586, 0.389189, 0.029445}, + {0.908174, 0.376178, 0.029445}, + {0.892468, 0.369672, 0.000000}, + {0.908174, 0.376178, -0.029445}, + {0.939586, 0.389189, -0.029445}, + {0.859740, 0.574460, 0.000000}, + {0.845605, 0.565015, 0.029445}, + {0.817335, 0.546126, 0.029445}, + {0.803200, 0.536681, 0.000000}, + {0.817335, 0.546126, -0.029445}, + {0.845605, 0.565015, -0.029445}, + {0.731148, 0.731148, 0.000000}, + {0.719128, 0.719128, 0.029445}, + {0.695086, 0.695086, 0.029445}, + {0.683065, 0.683065, 0.000000}, + {0.695086, 0.695086, -0.029445}, + {0.719128, 0.719128, -0.029445}, + {0.574460, 0.859740, 0.000000}, + {0.565015, 0.845605, 0.029445}, + {0.546125, 0.817335, 0.029445}, + {0.536681, 0.803200, 0.000000}, + {0.546125, 0.817335, -0.029445}, + {0.565015, 0.845605, -0.029445}, + {0.395695, 0.955291, 0.000000}, + {0.389189, 0.939585, 0.029445}, + {0.376178, 0.908173, 0.029445}, + {0.369672, 0.892467, 0.000000}, + {0.376178, 0.908173, -0.029445}, + {0.389189, 0.939585, -0.029445}, + {0.201724, 1.014132, 0.000000}, + {0.198407, 0.997459, 0.029445}, + {0.191774, 0.964112, 0.029445}, + {0.188457, 0.947439, 0.000000}, + {0.191774, 0.964112, -0.029445}, + {0.198407, 0.997459, -0.029445}, + {0.000000, 1.034000, 0.000000}, + {0.000000, 1.017000, 0.029445}, + {0.000000, 0.983000, 0.029445}, + {0.000000, 0.966000, 0.000000}, + {0.000000, 0.983000, -0.029445}, + {0.000000, 1.017000, -0.029445}, + {-0.201723, 1.014132, 0.000000}, + {-0.198407, 0.997459, 0.029445}, + {-0.191774, 0.964112, 0.029445}, + {-0.188457, 0.947439, 0.000000}, + {-0.191774, 0.964112, -0.029445}, + {-0.198407, 0.997459, -0.029445}, + {-0.395695, 0.955291, 0.000000}, + {-0.389189, 0.939585, 0.029445}, + {-0.376178, 0.908174, 0.029445}, + {-0.369672, 0.892468, 0.000000}, + {-0.376178, 0.908174, -0.029445}, + {-0.389189, 0.939585, -0.029445}, + {-0.574459, 0.859740, 0.000000}, + {-0.565015, 0.845605, 0.029445}, + {-0.546125, 0.817335, 0.029445}, + {-0.536681, 0.803200, 0.000000}, + {-0.546125, 0.817335, -0.029445}, + {-0.565015, 0.845605, -0.029445}, + {-0.731149, 0.731148, 0.000000}, + {-0.719128, 0.719127, 0.029445}, + {-0.695086, 0.695086, 0.029445}, + {-0.683065, 0.683065, 0.000000}, + {-0.695086, 0.695086, -0.029445}, + {-0.719128, 0.719127, -0.029445}, + {-0.859740, 0.574460, 0.000000}, + {-0.845604, 0.565015, 0.029445}, + {-0.817335, 0.546126, 0.029445}, + {-0.803200, 0.536681, 0.000000}, + {-0.817335, 0.546126, -0.029445}, + {-0.845604, 0.565015, -0.029445}, + {-0.955291, 0.395695, 0.000000}, + {-0.939585, 0.389189, 0.029445}, + {-0.908173, 0.376178, 0.029445}, + {-0.892468, 0.369672, 0.000000}, + {-0.908173, 0.376178, -0.029445}, + {-0.939585, 0.389189, -0.029445}, + {-1.014132, 0.201723, 0.000000}, + {-0.997459, 0.198407, 0.029445}, + {-0.964112, 0.191774, 0.029445}, + {-0.947439, 0.188457, 0.000000}, + {-0.964112, 0.191774, -0.029445}, + {-0.997459, 0.198407, -0.029445}, + {-1.034000, 0.000000, 0.000000}, + {-1.017000, 0.000000, 0.029445}, + {-0.983000, 0.000000, 0.029445}, + {-0.966000, 0.000000, 0.000000}, + {-0.983000, 0.000000, -0.029445}, + {-1.017000, 0.000000, -0.029445}, + {-1.014132, -0.201723, 0.000000}, + {-0.997459, -0.198407, 0.029445}, + {-0.964112, -0.191774, 0.029445}, + {-0.947439, -0.188457, 0.000000}, + {-0.964112, -0.191774, -0.029445}, + {-0.997459, -0.198407, -0.029445}, + {-0.955292, -0.395694, 0.000000}, + {-0.939586, -0.389189, 0.029445}, + {-0.908174, -0.376177, 0.029445}, + {-0.892468, -0.369672, 0.000000}, + {-0.908174, -0.376177, -0.029445}, + {-0.939586, -0.389189, -0.029445}, + {-0.859740, -0.574460, 0.000000}, + {-0.845604, -0.565015, 0.029445}, + {-0.817335, -0.546126, 0.029445}, + {-0.803200, -0.536681, 0.000000}, + {-0.817335, -0.546126, -0.029445}, + {-0.845604, -0.565015, -0.029445}, + {-0.731149, -0.731148, 0.000000}, + {-0.719128, -0.719127, 0.029445}, + {-0.695086, -0.695086, 0.029445}, + {-0.683065, -0.683065, 0.000000}, + {-0.695086, -0.695086, -0.029445}, + {-0.719128, -0.719127, -0.029445}, + {-0.574460, -0.859739, 0.000000}, + {-0.565015, -0.845604, 0.029445}, + {-0.546126, -0.817334, 0.029445}, + {-0.536681, -0.803199, 0.000000}, + {-0.546126, -0.817334, -0.029445}, + {-0.565015, -0.845604, -0.029445}, + {-0.395695, -0.955291, 0.000000}, + {-0.389189, -0.939585, 0.029445}, + {-0.376178, -0.908174, 0.029445}, + {-0.369672, -0.892468, 0.000000}, + {-0.376178, -0.908174, -0.029445}, + {-0.389189, -0.939585, -0.029445}, + {-0.201724, -1.014132, 0.000000}, + {-0.198407, -0.997459, 0.029445}, + {-0.191774, -0.964112, 0.029445}, + {-0.188458, -0.947438, 0.000000}, + {-0.191774, -0.964112, -0.029445}, + {-0.198407, -0.997459, -0.029445}, + {0.000000, -1.034000, 0.000000}, + {0.000000, -1.017000, 0.029445}, + {0.000000, -0.983000, 0.029445}, + {0.000000, -0.966000, 0.000000}, + {0.000000, -0.983000, -0.029445}, + {0.000000, -1.017000, -0.029445}, + {0.201723, -1.014132, 0.000000}, + {0.198407, -0.997459, 0.029445}, + {0.191773, -0.964112, 0.029445}, + {0.188457, -0.947439, 0.000000}, + {0.191773, -0.964112, -0.029445}, + {0.198407, -0.997459, -0.029445}, + {0.395695, -0.955291, 0.000000}, + {0.389189, -0.939585, 0.029445}, + {0.376178, -0.908173, 0.029445}, + {0.369672, -0.892467, 0.000000}, + {0.376178, -0.908173, -0.029445}, + {0.389189, -0.939585, -0.029445}, + {0.574460, -0.859740, 0.000000}, + {0.565015, -0.845605, 0.029445}, + {0.546125, -0.817335, 0.029445}, + {0.536681, -0.803200, 0.000000}, + {0.546125, -0.817335, -0.029445}, + {0.565015, -0.845605, -0.029445}, + {0.731148, -0.731149, 0.000000}, + {0.719127, -0.719128, 0.029445}, + {0.695086, -0.695086, 0.029445}, + {0.683065, -0.683066, 0.000000}, + {0.695086, -0.695086, -0.029445}, + {0.719127, -0.719128, -0.029445}, + {0.859740, -0.574460, 0.000000}, + {0.845605, -0.565015, 0.029445}, + {0.817335, -0.546126, 0.029445}, + {0.803200, -0.536681, 0.000000}, + {0.817335, -0.546126, -0.029445}, + {0.845605, -0.565015, -0.029445}, + {0.955291, -0.395695, 0.000000}, + {0.939585, -0.389189, 0.029445}, + {0.908173, -0.376178, 0.029445}, + {0.892467, -0.369673, 0.000000}, + {0.908173, -0.376178, -0.029445}, + {0.939585, -0.389189, -0.029445}, + {1.014132, -0.201723, 0.000000}, + {0.997459, -0.198407, 0.029445}, + {0.964112, -0.191774, 0.029445}, + {0.947439, -0.188457, 0.000000}, + {0.964112, -0.191774, -0.029445}, + {0.997459, -0.198407, -0.029445}, +}; + +static const float normals[][3] = { + {1.000000, 0.000000, 0.000000}, + {0.522691, 0.000000, 0.852504}, + {-0.475845, 0.000000, 0.879513}, + {-1.000000, 0.000000, 0.000000}, + {-0.475845, 0.000000, -0.879513}, + {0.522691, 0.000000, -0.852504}, + {0.980773, 0.195074, 0.000000}, + {0.512650, 0.101962, 0.852504}, + {-0.466689, -0.092807, 0.879513}, + {-0.980773, -0.195074, 0.000000}, + {-0.466689, -0.092807, -0.879513}, + {0.512650, 0.101962, -0.852504}, + {0.923856, 0.382672, 0.000000}, + {0.482894, 0.200018, 0.852504}, + {-0.439619, -0.182073, 0.879513}, + {-0.923856, -0.382672, 0.000000}, + {-0.439619, -0.182073, -0.879513}, + {0.482894, 0.200018, -0.852504}, + {0.831446, 0.555559, 0.000000}, + {0.434614, 0.290384, 0.852504}, + {-0.395642, -0.264351, 0.879513}, + {-0.831446, -0.555559, 0.000000}, + {-0.395642, -0.264351, -0.879513}, + {0.434614, 0.290384, -0.852504}, + {0.707083, 0.707083, 0.000000}, + {0.369610, 0.369610, 0.852504}, + {-0.336467, -0.336467, 0.879513}, + {-0.707083, -0.707083, 0.000000}, + {-0.336467, -0.336467, -0.879513}, + {0.369610, 0.369610, -0.852504}, + {0.555559, 0.831446, 0.000000}, + {0.290384, 0.434614, 0.852504}, + {-0.264351, -0.395642, 0.879513}, + {-0.555559, -0.831446, 0.000000}, + {-0.264351, -0.395642, -0.879513}, + {0.290384, 0.434614, -0.852504}, + {0.382672, 0.923856, 0.000000}, + {0.200018, 0.482894, 0.852504}, + {-0.182073, -0.439619, 0.879513}, + {-0.382672, -0.923856, 0.000000}, + {-0.182073, -0.439619, -0.879513}, + {0.200018, 0.482894, -0.852504}, + {0.195074, 0.980773, 0.000000}, + {0.101962, 0.512650, 0.852504}, + {-0.092807, -0.466689, 0.879513}, + {-0.195074, -0.980773, 0.000000}, + {-0.092807, -0.466689, -0.879513}, + {0.101962, 0.512650, -0.852504}, + {0.000000, 1.000000, 0.000000}, + {0.000000, 0.522691, 0.852504}, + {0.000000, -0.475845, 0.879513}, + {0.000000, -1.000000, 0.000000}, + {0.000000, -0.475845, -0.879513}, + {0.000000, 0.522691, -0.852504}, + {-0.195074, 0.980773, 0.000000}, + {-0.101962, 0.512650, 0.852504}, + {0.092807, -0.466689, 0.879513}, + {0.195074, -0.980773, 0.000000}, + {0.092807, -0.466689, -0.879513}, + {-0.101962, 0.512650, -0.852504}, + {-0.382672, 0.923856, 0.000000}, + {-0.200018, 0.482894, 0.852504}, + {0.182073, -0.439619, 0.879513}, + {0.382672, -0.923856, 0.000000}, + {0.182073, -0.439619, -0.879513}, + {-0.200018, 0.482894, -0.852504}, + {-0.555559, 0.831446, 0.000000}, + {-0.290384, 0.434614, 0.852504}, + {0.264351, -0.395642, 0.879513}, + {0.555559, -0.831446, 0.000000}, + {0.264351, -0.395642, -0.879513}, + {-0.290384, 0.434614, -0.852504}, + {-0.707083, 0.707083, 0.000000}, + {-0.369610, 0.369610, 0.852504}, + {0.336467, -0.336467, 0.879513}, + {0.707083, -0.707083, 0.000000}, + {0.336467, -0.336467, -0.879513}, + {-0.369610, 0.369610, -0.852504}, + {-0.831446, 0.555559, 0.000000}, + {-0.434614, 0.290384, 0.852504}, + {0.395642, -0.264351, 0.879513}, + {0.831446, -0.555559, 0.000000}, + {0.395642, -0.264351, -0.879513}, + {-0.434614, 0.290384, -0.852504}, + {-0.923856, 0.382672, 0.000000}, + {-0.482894, 0.200018, 0.852504}, + {0.439619, -0.182073, 0.879513}, + {0.923856, -0.382672, 0.000000}, + {0.439619, -0.182073, -0.879513}, + {-0.482894, 0.200018, -0.852504}, + {-0.980773, 0.195074, 0.000000}, + {-0.512650, 0.101962, 0.852504}, + {0.466689, -0.092807, 0.879513}, + {0.980773, -0.195074, 0.000000}, + {0.466689, -0.092807, -0.879513}, + {-0.512650, 0.101962, -0.852504}, + {-1.000000, 0.000000, 0.000000}, + {-0.522691, 0.000000, 0.852504}, + {0.475845, 0.000000, 0.879513}, + {1.000000, 0.000000, 0.000000}, + {0.475845, 0.000000, -0.879513}, + {-0.522691, 0.000000, -0.852504}, + {-0.980773, -0.195074, 0.000000}, + {-0.512650, -0.101962, 0.852504}, + {0.466689, 0.092807, 0.879513}, + {0.980773, 0.195074, 0.000000}, + {0.466689, 0.092807, -0.879513}, + {-0.512650, -0.101962, -0.852504}, + {-0.923856, -0.382672, 0.000000}, + {-0.482894, -0.200018, 0.852504}, + {0.439619, 0.182073, 0.879513}, + {0.923856, 0.382672, 0.000000}, + {0.439619, 0.182073, -0.879513}, + {-0.482894, -0.200018, -0.852504}, + {-0.831446, -0.555559, 0.000000}, + {-0.434614, -0.290384, 0.852504}, + {0.395642, 0.264351, 0.879513}, + {0.831446, 0.555559, 0.000000}, + {0.395642, 0.264351, -0.879513}, + {-0.434614, -0.290384, -0.852504}, + {-0.707083, -0.707083, 0.000000}, + {-0.369610, -0.369610, 0.852504}, + {0.336467, 0.336467, 0.879513}, + {0.707083, 0.707083, 0.000000}, + {0.336467, 0.336467, -0.879513}, + {-0.369610, -0.369610, -0.852504}, + {-0.555559, -0.831446, 0.000000}, + {-0.290384, -0.434614, 0.852504}, + {0.264351, 0.395642, 0.879513}, + {0.555559, 0.831446, 0.000000}, + {0.264351, 0.395642, -0.879513}, + {-0.290384, -0.434614, -0.852504}, + {-0.382672, -0.923856, 0.000000}, + {-0.200018, -0.482894, 0.852504}, + {0.182073, 0.439619, 0.879513}, + {0.382672, 0.923856, 0.000000}, + {0.182073, 0.439619, -0.879513}, + {-0.200018, -0.482894, -0.852504}, + {-0.195074, -0.980773, 0.000000}, + {-0.101962, -0.512650, 0.852504}, + {0.092807, 0.466689, 0.879513}, + {0.195074, 0.980773, 0.000000}, + {0.092807, 0.466689, -0.879513}, + {-0.101962, -0.512650, -0.852504}, + {0.000000, -1.000000, 0.000000}, + {0.000000, -0.522691, 0.852504}, + {0.000000, 0.475845, 0.879513}, + {0.000000, 1.000000, 0.000000}, + {0.000000, 0.475845, -0.879513}, + {0.000000, -0.522691, -0.852504}, + {0.195074, -0.980773, 0.000000}, + {0.101962, -0.512650, 0.852504}, + {-0.092807, 0.466689, 0.879513}, + {-0.195074, 0.980773, 0.000000}, + {-0.092807, 0.466689, -0.879513}, + {0.101962, -0.512650, -0.852504}, + {0.382672, -0.923856, 0.000000}, + {0.200018, -0.482894, 0.852504}, + {-0.182073, 0.439619, 0.879513}, + {-0.382672, 0.923856, 0.000000}, + {-0.182073, 0.439619, -0.879513}, + {0.200018, -0.482894, -0.852504}, + {0.555559, -0.831446, 0.000000}, + {0.290384, -0.434614, 0.852504}, + {-0.264351, 0.395642, 0.879513}, + {-0.555559, 0.831446, 0.000000}, + {-0.264351, 0.395642, -0.879513}, + {0.290384, -0.434614, -0.852504}, + {0.707083, -0.707083, 0.000000}, + {0.369610, -0.369610, 0.852504}, + {-0.336467, 0.336467, 0.879513}, + {-0.707083, 0.707083, 0.000000}, + {-0.336467, 0.336467, -0.879513}, + {0.369610, -0.369610, -0.852504}, + {0.831446, -0.555559, 0.000000}, + {0.434614, -0.290384, 0.852504}, + {-0.395642, 0.264351, 0.879513}, + {-0.831446, 0.555559, 0.000000}, + {-0.395642, 0.264351, -0.879513}, + {0.434614, -0.290384, -0.852504}, + {0.923856, -0.382672, 0.000000}, + {0.482894, -0.200018, 0.852504}, + {-0.439619, 0.182073, 0.879513}, + {-0.923856, 0.382672, 0.000000}, + {-0.439619, 0.182073, -0.879513}, + {0.482894, -0.200018, -0.852504}, + {0.980773, -0.195074, 0.000000}, + {0.512650, -0.101962, 0.852504}, + {-0.466689, 0.092807, 0.879513}, + {-0.980773, 0.195074, 0.000000}, + {-0.466689, 0.092807, -0.879513}, + {0.512650, -0.101962, -0.852504}, +}; + +static const unsigned short indices[] = { + 6, 7, 1, + 7, 8, 2, + 8, 9, 3, + 9, 10, 4, + 10, 11, 5, + 5, 11, 6, + 12, 13, 7, + 13, 14, 8, + 14, 15, 9, + 15, 16, 10, + 16, 17, 11, + 11, 17, 12, + 18, 19, 13, + 13, 19, 20, + 20, 21, 15, + 15, 21, 22, + 22, 23, 17, + 17, 23, 18, + 24, 25, 19, + 19, 25, 26, + 26, 27, 21, + 21, 27, 28, + 28, 29, 23, + 23, 29, 24, + 30, 31, 25, + 25, 31, 32, + 26, 32, 33, + 27, 33, 34, + 34, 35, 29, + 29, 35, 30, + 36, 37, 31, + 31, 37, 38, + 38, 39, 33, + 39, 40, 34, + 40, 41, 35, + 35, 41, 36, + 36, 42, 43, + 43, 44, 38, + 44, 45, 39, + 45, 46, 40, + 46, 47, 41, + 47, 42, 36, + 48, 49, 43, + 49, 50, 44, + 50, 51, 45, + 51, 52, 46, + 52, 53, 47, + 47, 53, 48, + 54, 55, 49, + 49, 55, 56, + 50, 56, 57, + 57, 58, 52, + 58, 59, 53, + 53, 59, 54, + 60, 61, 55, + 55, 61, 62, + 56, 62, 63, + 63, 64, 58, + 64, 65, 59, + 59, 65, 60, + 66, 67, 61, + 61, 67, 68, + 68, 69, 63, + 69, 70, 64, + 70, 71, 65, + 71, 66, 60, + 72, 73, 67, + 73, 74, 68, + 68, 74, 75, + 75, 76, 70, + 76, 77, 71, + 71, 77, 72, + 78, 79, 73, + 79, 80, 74, + 74, 80, 81, + 81, 82, 76, + 82, 83, 77, + 83, 78, 72, + 78, 84, 85, + 85, 86, 80, + 80, 86, 87, + 87, 88, 82, + 82, 88, 89, + 89, 84, 78, + 90, 91, 85, + 91, 92, 86, + 86, 92, 93, + 93, 94, 88, + 88, 94, 95, + 95, 90, 84, + 96, 97, 91, + 97, 98, 92, + 98, 99, 93, + 99, 100, 94, + 100, 101, 95, + 101, 96, 90, + 102, 103, 97, + 103, 104, 98, + 104, 105, 99, + 99, 105, 106, + 106, 107, 101, + 101, 107, 102, + 108, 109, 103, + 103, 109, 110, + 110, 111, 105, + 105, 111, 112, + 112, 113, 107, + 107, 113, 108, + 114, 115, 109, + 115, 116, 110, + 116, 117, 111, + 111, 117, 118, + 112, 118, 119, + 113, 119, 114, + 114, 120, 121, + 121, 122, 116, + 122, 123, 117, + 117, 123, 124, + 124, 125, 119, + 125, 120, 114, + 126, 127, 121, + 121, 127, 128, + 128, 129, 123, + 123, 129, 130, + 130, 131, 125, + 125, 131, 126, + 132, 133, 127, + 133, 134, 128, + 128, 134, 135, + 135, 136, 130, + 136, 137, 131, + 131, 137, 132, + 132, 138, 139, + 133, 139, 140, + 134, 140, 141, + 141, 142, 136, + 142, 143, 137, + 143, 138, 132, + 138, 144, 145, + 139, 145, 146, + 146, 147, 141, + 141, 147, 148, + 148, 149, 143, + 149, 144, 138, + 144, 150, 151, + 151, 152, 146, + 146, 152, 153, + 153, 154, 148, + 154, 155, 149, + 155, 150, 144, + 156, 157, 151, + 151, 157, 158, + 158, 159, 153, + 159, 160, 154, + 160, 161, 155, + 155, 161, 156, + 156, 162, 163, + 163, 164, 158, + 158, 164, 165, + 165, 166, 160, + 160, 166, 167, + 167, 162, 156, + 162, 168, 169, + 169, 170, 164, + 164, 170, 171, + 165, 171, 172, + 166, 172, 173, + 173, 168, 162, + 174, 175, 169, + 175, 176, 170, + 170, 176, 177, + 177, 178, 172, + 172, 178, 179, + 173, 179, 174, + 174, 180, 181, + 181, 182, 176, + 176, 182, 183, + 183, 184, 178, + 178, 184, 185, + 179, 185, 180, + 186, 187, 181, + 187, 188, 182, + 188, 189, 183, + 183, 189, 190, + 190, 191, 185, + 191, 186, 180, + 0, 1, 187, + 1, 2, 188, + 2, 3, 189, + 3, 4, 190, + 190, 4, 5, + 191, 5, 0, + 0, 6, 1, + 1, 7, 2, + 2, 8, 3, + 3, 9, 4, + 4, 10, 5, + 0, 5, 6, + 6, 12, 7, + 7, 13, 8, + 8, 14, 9, + 9, 15, 10, + 10, 16, 11, + 6, 11, 12, + 12, 18, 13, + 14, 13, 20, + 14, 20, 15, + 16, 15, 22, + 16, 22, 17, + 12, 17, 18, + 18, 24, 19, + 20, 19, 26, + 20, 26, 21, + 22, 21, 28, + 22, 28, 23, + 18, 23, 24, + 24, 30, 25, + 26, 25, 32, + 27, 26, 33, + 28, 27, 34, + 28, 34, 29, + 24, 29, 30, + 30, 36, 31, + 32, 31, 38, + 32, 38, 33, + 33, 39, 34, + 34, 40, 35, + 30, 35, 36, + 37, 36, 43, + 37, 43, 38, + 38, 44, 39, + 39, 45, 40, + 40, 46, 41, + 41, 47, 36, + 42, 48, 43, + 43, 49, 44, + 44, 50, 45, + 45, 51, 46, + 46, 52, 47, + 42, 47, 48, + 48, 54, 49, + 50, 49, 56, + 51, 50, 57, + 51, 57, 52, + 52, 58, 53, + 48, 53, 54, + 54, 60, 55, + 56, 55, 62, + 57, 56, 63, + 57, 63, 58, + 58, 64, 59, + 54, 59, 60, + 60, 66, 61, + 62, 61, 68, + 62, 68, 63, + 63, 69, 64, + 64, 70, 65, + 65, 71, 60, + 66, 72, 67, + 67, 73, 68, + 69, 68, 75, + 69, 75, 70, + 70, 76, 71, + 66, 71, 72, + 72, 78, 73, + 73, 79, 74, + 75, 74, 81, + 75, 81, 76, + 76, 82, 77, + 77, 83, 72, + 79, 78, 85, + 79, 85, 80, + 81, 80, 87, + 81, 87, 82, + 83, 82, 89, + 83, 89, 78, + 84, 90, 85, + 85, 91, 86, + 87, 86, 93, + 87, 93, 88, + 89, 88, 95, + 89, 95, 84, + 90, 96, 91, + 91, 97, 92, + 92, 98, 93, + 93, 99, 94, + 94, 100, 95, + 95, 101, 90, + 96, 102, 97, + 97, 103, 98, + 98, 104, 99, + 100, 99, 106, + 100, 106, 101, + 96, 101, 102, + 102, 108, 103, + 104, 103, 110, + 104, 110, 105, + 106, 105, 112, + 106, 112, 107, + 102, 107, 108, + 108, 114, 109, + 109, 115, 110, + 110, 116, 111, + 112, 111, 118, + 113, 112, 119, + 108, 113, 114, + 115, 114, 121, + 115, 121, 116, + 116, 122, 117, + 118, 117, 124, + 118, 124, 119, + 119, 125, 114, + 120, 126, 121, + 122, 121, 128, + 122, 128, 123, + 124, 123, 130, + 124, 130, 125, + 120, 125, 126, + 126, 132, 127, + 127, 133, 128, + 129, 128, 135, + 129, 135, 130, + 130, 136, 131, + 126, 131, 132, + 133, 132, 139, + 134, 133, 140, + 135, 134, 141, + 135, 141, 136, + 136, 142, 137, + 137, 143, 132, + 139, 138, 145, + 140, 139, 146, + 140, 146, 141, + 142, 141, 148, + 142, 148, 143, + 143, 149, 138, + 145, 144, 151, + 145, 151, 146, + 147, 146, 153, + 147, 153, 148, + 148, 154, 149, + 149, 155, 144, + 150, 156, 151, + 152, 151, 158, + 152, 158, 153, + 153, 159, 154, + 154, 160, 155, + 150, 155, 156, + 157, 156, 163, + 157, 163, 158, + 159, 158, 165, + 159, 165, 160, + 161, 160, 167, + 161, 167, 156, + 163, 162, 169, + 163, 169, 164, + 165, 164, 171, + 166, 165, 172, + 167, 166, 173, + 167, 173, 162, + 168, 174, 169, + 169, 175, 170, + 171, 170, 177, + 171, 177, 172, + 173, 172, 179, + 168, 173, 174, + 175, 174, 181, + 175, 181, 176, + 177, 176, 183, + 177, 183, 178, + 179, 178, 185, + 174, 179, 180, + 180, 186, 181, + 181, 187, 182, + 182, 188, 183, + 184, 183, 190, + 184, 190, 185, + 185, 191, 180, + 186, 0, 187, + 187, 1, 188, + 188, 2, 189, + 189, 3, 190, + 191, 190, 5, + 186, 191, 0, +}; + +ManipulatorGeomInfo wm_manipulator_geom_data_dial = { + .nverts = 192, + .ntris = 384, + .verts = verts, + .normals = normals, + .indices = indices, +}; diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h b/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h new file mode 100644 index 00000000000..b3df79834a3 --- /dev/null +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h @@ -0,0 +1,51 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2016 Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h + * \ingroup wm + * + * \name Manipulator Geometry + * + * \brief Prototypes for arrays defining the manipulator geometry. The actual definitions can be found in files usually + * called geom_xxx_manipulator.c + */ + + +#ifndef __MANIPULATOR_GEOMETRY_H__ +#define __MANIPULATOR_GEOMETRY_H__ + +typedef struct ManipulatorGeomInfo { + int nverts; + int ntris; + const float (*verts)[3]; + const float (*normals)[3]; + const unsigned short *indices; +} ManipulatorGeomInfo; + +/* arrow manipulator */ +extern ManipulatorGeomInfo wm_manipulator_geom_data_arrow; + +/* cube manipulator */ +extern ManipulatorGeomInfo wm_manipulator_geom_data_cube; + +#endif /* __MANIPULATOR_GEOMETRY_H__ */ diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_intern.h b/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_intern.h index 66598fa29d7..e432fa1523a 100644 --- a/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_intern.h +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_intern.h @@ -77,23 +77,23 @@ float manipulator_value_from_offset( const bool constrained, const bool inverted, const bool use_precision); void manipulator_property_data_update( - wmManipulator *manipulator, ManipulatorCommonData *data, const int slot, + struct wmManipulator *manipulator, ManipulatorCommonData *data, const int slot, const bool constrained, const bool inverted); void manipulator_property_value_set( - bContext *C, const wmManipulator *manipulator, + bContext *C, const struct wmManipulator *manipulator, const int slot, const float value); float manipulator_property_value_get( - const wmManipulator *manipulator, const int slot); + const struct wmManipulator *manipulator, const int slot); void manipulator_property_value_reset( - bContext *C, const wmManipulator *manipulator, ManipulatorInteraction *inter, + bContext *C, const struct wmManipulator *manipulator, ManipulatorInteraction *inter, const int slot); /* -------------------------------------------------------------------- */ void manipulator_color_get( - const wmManipulator *manipulator, const bool highlight, + const struct wmManipulator *manipulator, const bool highlight, float r_col[]); #endif /* __MANIPULATOR_LIBRARY_INTERN_H__ */ diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c new file mode 100644 index 00000000000..5a0700359d8 --- /dev/null +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c @@ -0,0 +1,248 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c + * \ingroup wm + * + * \name Primitive Manipulator + * + * 3D Manipulator + * + * \brief Manipulator with primitive drawing type (plane, cube, etc.). + * Currently only plane primitive supported without own handling, use with operator only. + */ + +#include "BIF_gl.h" + +#include "BKE_context.h" + +#include "BLI_math.h" + +#include "DNA_view3d_types.h" +#include "DNA_manipulator_types.h" + +#include "GPU_select.h" + +#include "MEM_guardedalloc.h" + +#include "WM_api.h" +#include "WM_types.h" + +/* own includes */ +#include "WM_manipulator_types.h" +#include "WM_manipulator_library.h" +#include "wm_manipulator_wmapi.h" +#include "wm_manipulator_intern.h" +#include "manipulator_library_intern.h" + + +/* PrimitiveManipulator->flag */ +enum { + PRIM_UP_VECTOR_SET = (1 << 0), +}; + +typedef struct PrimitiveManipulator { + wmManipulator manipulator; + + float direction[3]; + float up[3]; + int style; + int flag; +} PrimitiveManipulator; + + +static float verts_plane[4][3] = { + {-1, -1, 0}, + { 1, -1, 0}, + { 1, 1, 0}, + {-1, 1, 0}, +}; + + +/* -------------------------------------------------------------------- */ + +static void manipulator_primitive_draw_geom( + const float col_inner[4], const float col_outer[4], const int style) +{ + float (*verts)[3]; + float vert_count; + + if (style == MANIPULATOR_PRIMITIVE_STYLE_PLANE) { + verts = verts_plane; + vert_count = ARRAY_SIZE(verts_plane); + } + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, verts); + glColor4fv(col_inner); + glDrawArrays(GL_QUADS, 0, vert_count); + glColor4fv(col_outer); + glDrawArrays(GL_LINE_LOOP, 0, vert_count); + glDisableClientState(GL_VERTEX_ARRAY); +} + +static void manipulator_primitive_draw_intern( + PrimitiveManipulator *prim, const bool UNUSED(select), + const bool highlight) +{ + float col_inner[4], col_outer[4]; + float rot[3][3]; + float mat[4][4]; + + if (prim->flag & PRIM_UP_VECTOR_SET) { + copy_v3_v3(rot[2], prim->direction); + copy_v3_v3(rot[1], prim->up); + cross_v3_v3v3(rot[0], prim->up, prim->direction); + } + else { + const float up[3] = {0.0f, 0.0f, 1.0f}; + rotation_between_vecs_to_mat3(rot, up, prim->direction); + } + + copy_m4_m3(mat, rot); + copy_v3_v3(mat[3], prim->manipulator.origin); + mul_mat3_m4_fl(mat, prim->manipulator.scale); + + glPushMatrix(); + glMultMatrixf(mat); + + manipulator_color_get(&prim->manipulator, highlight, col_outer); + copy_v4_v4(col_inner, col_outer); + col_inner[3] *= 0.5f; + + glEnable(GL_BLEND); + glTranslatef(UNPACK3(prim->manipulator.offset)); + manipulator_primitive_draw_geom(col_inner, col_outer, prim->style); + glDisable(GL_BLEND); + + glPopMatrix(); + + if (prim->manipulator.interaction_data) { + ManipulatorInteraction *inter = prim->manipulator.interaction_data; + + copy_v4_fl(col_inner, 0.5f); + copy_v3_fl(col_outer, 0.5f); + col_outer[3] = 0.8f; + + copy_m4_m3(mat, rot); + copy_v3_v3(mat[3], inter->init_origin); + mul_mat3_m4_fl(mat, inter->init_scale); + + glPushMatrix(); + glMultMatrixf(mat); + + glEnable(GL_BLEND); + glTranslatef(UNPACK3(prim->manipulator.offset)); + manipulator_primitive_draw_geom(col_inner, col_outer, prim->style); + glDisable(GL_BLEND); + + glPopMatrix(); + } +} + +static void manipulator_primitive_render_3d_intersect( + const bContext *UNUSED(C), wmManipulator *manipulator, + int selectionbase) +{ + GPU_select_load_id(selectionbase); + manipulator_primitive_draw_intern((PrimitiveManipulator *)manipulator, true, false); +} + +static void manipulator_primitive_draw(const bContext *UNUSED(C), wmManipulator *manipulator) +{ + manipulator_primitive_draw_intern( + (PrimitiveManipulator *)manipulator, false, + (manipulator->state & WM_MANIPULATOR_HIGHLIGHT)); +} + +static int manipulator_primitive_invoke( + bContext *UNUSED(C), const wmEvent *UNUSED(event), wmManipulator *manipulator) +{ + ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__); + + copy_v3_v3(inter->init_origin, manipulator->origin); + inter->init_scale = manipulator->scale; + + manipulator->interaction_data = inter; + + return OPERATOR_RUNNING_MODAL; +} + + +/* -------------------------------------------------------------------- */ +/** \name Primitive Manipulator API + * + * \{ */ + +wmManipulator *MANIPULATOR_primitive_new(wmManipulatorGroup *mgroup, const char *name, const int style) +{ + PrimitiveManipulator *prim = MEM_callocN(sizeof(PrimitiveManipulator), name); + const float dir_default[3] = {0.0f, 0.0f, 1.0f}; + + prim->manipulator.draw = manipulator_primitive_draw; + prim->manipulator.invoke = manipulator_primitive_invoke; + prim->manipulator.intersect = NULL; + prim->manipulator.render_3d_intersection = manipulator_primitive_render_3d_intersect; + prim->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE; + prim->style = style; + + /* defaults */ + copy_v3_v3(prim->direction, dir_default); + + wm_manipulator_register(mgroup, &prim->manipulator, name); + + return (wmManipulator *)prim; +} + +/** + * Define direction the primitive will point towards + */ +void MANIPULATOR_primitive_set_direction(wmManipulator *manipulator, const float direction[3]) +{ + PrimitiveManipulator *prim = (PrimitiveManipulator *)manipulator; + + normalize_v3_v3(prim->direction, direction); +} + +/** + * Define up-direction of the primitive manipulator + */ +void MANIPULATOR_primitive_set_up_vector(wmManipulator *manipulator, const float direction[3]) +{ + PrimitiveManipulator *prim = (PrimitiveManipulator *)manipulator; + + if (direction) { + normalize_v3_v3(prim->up, direction); + prim->flag |= PRIM_UP_VECTOR_SET; + } + else { + prim->flag &= ~PRIM_UP_VECTOR_SET; + } +} + +/** \} */ // Primitive Manipulator API + + +/* -------------------------------------------------------------------- */ + +void fix_linking_manipulator_primitive(void) +{ + (void)0; +} diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c index 7fdbb0d6324..b82a7469520 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c @@ -34,6 +34,8 @@ #include "BLI_string.h" #include "BLI_string_utils.h" +#include "DNA_manipulator_types.h" + #include "ED_screen.h" #include "ED_view3d.h" @@ -50,6 +52,59 @@ #include "wm_manipulator_wmapi.h" #include "wm_manipulator_intern.h" +#include "manipulator_library/manipulator_geometry.h" + +/** + * Main draw call for ManipulatorGeomInfo data + */ +void wm_manipulator_geometryinfo_draw(const ManipulatorGeomInfo *info, const bool select) +{ + GLuint buf[3]; + const bool use_lighting = !select && ((U.manipulator_flag & V3D_SHADED_MANIPULATORS) != 0); + + if (use_lighting) + glGenBuffers(3, buf); + else + glGenBuffers(2, buf); + + 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); + + 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); + } + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * (3 * info->ntris), info->indices, GL_STATIC_DRAW); + + glEnable(GL_CULL_FACE); + // glEnable(GL_DEPTH_TEST); + + glDrawElements(GL_TRIANGLES, info->ntris * 3, GL_UNSIGNED_SHORT, NULL); + + 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); + } +} /* Still unused */ wmManipulator *WM_manipulator_new( @@ -66,12 +121,11 @@ wmManipulator *WM_manipulator_new( manipulator->render_3d_intersection = render_3d_intersection; /* XXX */ -// fix_linking_manipulator_arrow(); -// fix_linking_manipulator_arrow2d(); -// fix_linking_manipulator_cage(); -// fix_linking_manipulator_dial(); -// fix_linking_manipulator_facemap(); -// fix_linking_manipulator_primitive(); + fix_linking_manipulator_arrow(); + fix_linking_manipulator_arrow2d(); + fix_linking_manipulator_cage(); + fix_linking_manipulator_dial(); + fix_linking_manipulator_primitive(); return manipulator; } @@ -207,6 +261,14 @@ PointerRNA *WM_manipulator_set_operator(wmManipulator *manipulator, const char * return NULL; } + +void WM_manipulator_set_custom_handler( + struct wmManipulator *manipulator, + int (*handler)(struct bContext *, const wmEvent *, struct wmManipulator *, const int)) +{ + manipulator->handler = handler; +} + /** * \brief Set manipulator select callback. * @@ -341,7 +403,7 @@ void wm_manipulator_calculate_scale(wmManipulator *manipulator, const bContext * float scale = 1.0f; if (manipulator->mgroup->type->flag & WM_MANIPULATORGROUPTYPE_SCALE_3D) { - if (rv3d /*&& (U.manipulator_flag & V3D_3D_MANIPULATORS) == 0*/) { /* UserPref flag might be useful for later */ + if (rv3d /*&& (U.manipulator_flag & V3D_DRAW_MANIPULATOR) == 0*/) { /* UserPref flag might be useful for later */ if (manipulator->get_final_position) { float position[3]; diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h index fd060c79b2c..a1ea4bfc8ae 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h @@ -30,6 +30,7 @@ struct wmKeyConfig; struct wmManipulatorMap; +struct ManipulatorGeomInfo; /* -------------------------------------------------------------------- */ /* wmManipulator */ @@ -154,8 +155,8 @@ enum { struct wmManipulatorGroup *wm_manipulatorgroup_new_from_type(struct wmManipulatorGroupType *mgrouptype); void wm_manipulatorgroup_free(bContext *C, struct wmManipulatorMap *mmap, struct wmManipulatorGroup *mgroup); -void wm_manipulatorgroup_manipulator_register(struct wmManipulatorGroup *mgroup, wmManipulator *manipulator); -wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator( +void wm_manipulatorgroup_manipulator_register(struct wmManipulatorGroup *mgroup, struct wmManipulator *manipulator); +struct wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator( const struct wmManipulatorGroup *mgroup, struct bContext *C, const struct wmEvent *event, unsigned char *part); void wm_manipulatorgroup_intersectable_manipulators_to_list( @@ -210,21 +211,14 @@ struct wmManipulatorMapType { ListBase manipulator_grouptypes; }; -void wm_manipulatormap_selected_delete(wmManipulatorMap *mmap); -bool wm_manipulatormap_deselect_all(struct wmManipulatorMap *mmap, wmManipulator ***sel); +void wm_manipulatormap_selected_delete(struct wmManipulatorMap *mmap); +bool wm_manipulatormap_deselect_all(struct wmManipulatorMap *mmap, struct wmManipulator ***sel); /* -------------------------------------------------------------------- */ /* Manipulator drawing */ -typedef struct ManipulatorGeometryInfo { - int nverts; - int ntris; - float (*verts)[3]; - float (*normals)[3]; - unsigned short *indices; - bool init; -} ManipulatorGeometryInfo; +void wm_manipulator_geometryinfo_draw(const struct ManipulatorGeomInfo *info, const bool select); #endif /* __WM_MANIPULATOR_INTERN_H__ */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c index f9f46b0f71a..5074c6d0257 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c @@ -43,6 +43,8 @@ #include "BPY_extern.h" +#include "DNA_manipulator_types.h" + #include "ED_screen.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c index 2dd02450dcf..3c3beed73fb 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c @@ -36,6 +36,8 @@ #include "BLI_string.h" #include "BLI_ghash.h" +#include "DNA_manipulator_types.h" + #include "ED_screen.h" #include "ED_view3d.h" @@ -237,6 +239,30 @@ static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext return; BLI_assert(!BLI_listbase_is_empty(&mmap->manipulator_groups)); + const bool draw_multisample = (U.ogl_multisamples != USER_MULTISAMPLE_NONE); + const bool use_lighting = (U.manipulator_flag & V3D_SHADED_MANIPULATORS) != 0; + + /* enable multisampling */ + if (draw_multisample) { + glEnable(GL_MULTISAMPLE); + } + if (use_lighting) { + const float lightpos[4] = {0.0, 0.0, 1.0, 0.0}; + const float diffuse[4] = {1.0, 1.0, 1.0, 0.0}; + + glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glPushMatrix(); + glLoadIdentity(); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glPopMatrix(); + } + /* draw_manipulators contains all visible manipulators - draw them */ for (LinkData *link = draw_manipulators->first, *link_next; link; link = link_next) { wmManipulator *manipulator = link->data; @@ -246,6 +272,13 @@ static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext /* free/remove manipulator link after drawing */ BLI_freelinkN(draw_manipulators, link); } + + if (draw_multisample) { + glDisable(GL_MULTISAMPLE); + } + if (use_lighting) { + glPopAttrib(); + } } void WM_manipulatormap_draw(wmManipulatorMap *mmap, const bContext *C, const int drawstep) |