1
1

Compare commits

...

28 Commits

Author SHA1 Message Date
Julian Eisel
7576ad3d04 Merge branch 'blender2.8' into transform-manipulators
Conflicts:
	intern/gawain/gawain/immediate.h
	intern/gawain/src/immediate.c
	source/blender/editors/physics/physics_ops.c
	source/blender/editors/screen/glutil.c
	source/blender/editors/space_view3d/space_view3d.c
	source/blender/editors/space_view3d/view3d_draw.c
	source/blender/editors/space_view3d/view3d_edit.c
	source/blender/editors/space_view3d/view3d_ops.c
	source/blender/editors/transform/transform_manipulator.c
2017-04-04 21:39:57 +02:00
Julian Eisel
10b24eabba Merge branch 'blender2.8' into transform-manipulators
Conflicts:
	source/blender/editors/interface/resources.c
	source/blender/editors/space_view3d/view3d_intern.h
	source/blender/editors/transform/transform_manipulator.c
	source/blender/gpu/CMakeLists.txt
	source/blender/gpu/intern/gpu_shader.c
2017-02-12 21:43:13 +01:00
Julian Eisel
f754ce1c5e Merge branch 'blender2.8' into transform-manipulators 2017-01-30 00:21:36 +01:00
Julian Eisel
418d931490 Merge branch 'blender2.8' into transform-manipulators 2017-01-20 17:05:16 +01:00
Julian Eisel
a075c8a0b4 Merge branch 'blender2.8' into transform-manipulators
Conflicts:
	source/blender/editors/space_view3d/view3d_edit.c
	source/blender/editors/space_view3d/view3d_ops.c
	source/blender/editors/transform/transform_manipulator.c
2017-01-14 17:53:20 +01:00
Julian Eisel
52328be974 Merge branch 'blender2.8' into transform-manipulators 2016-12-15 22:20:47 +01:00
Julian Eisel
ece7b7dc53 Merge branch 'blender2.8' into transform-manipulators
Conflicts:
	source/blender/blenloader/intern/versioning_270.c
	source/blender/editors/interface/resources.c
	source/blender/editors/screen/glutil.c
	source/blender/gpu/intern/gpu_shader.c
2016-11-29 13:23:05 +01:00
Julian Eisel
9888e1e3d4 Fix out of bound array access
And other minor fixes.
2016-11-29 13:02:12 +01:00
Julian Eisel
d5def0bedf Use axes colors from custom-manipulators branch 2016-11-10 23:24:08 +01:00
Julian Eisel
723e0a5e01 Don't draw helplines when using transform manipulators
Also removed unused transform flag.
2016-11-10 23:07:26 +01:00
Julian Eisel
380aacb12a Remove bad storage hacks of old transform manipulators
Got rid of Scene.twcent, Scene.twmin, Scene.twmax, RegionView3D.twmat, RegionView3D.twdrawflag, RegionView3D.tw_idot, TransInfo.mat, TransInfo.vec.
Also cleaned-up variable and define names.

Decided to completely remove the struct members without doing proper file conversion for non-runtime ones. That will cause minor compatibility breakage but that's okay for 2.8.
2016-11-09 01:00:39 +01:00
Julian Eisel
90fcbde62d Remove old transform manipulators code 2016-11-08 21:22:12 +01:00
Julian Eisel
077ac7b302 Merge branch 'blender2.8' into transform-manipulators
Conflicts:
	source/blender/gpu/intern/gpu_shader.c
2016-11-08 20:42:52 +01:00
Julian Eisel
87fd59406b Rotation value indicator for rotation manipulators
Adds the arc thingy that displays the current delta rotation value while rotating.
It is a different implementation than the one of the custom-manipulators branch which was based on mouse coordinates and thus didn't work correctly with snapping and precision (shift) tweaking. This new implementation is based on object matrix and fixes these issues.

Commit only adds support for rotating objects, not yet for other elements (polygons, bones, GPencil points, etc)
Also some minor cleanup of course ;)
2016-11-08 20:36:11 +01:00
Julian Eisel
754eaf45ff Make transform manipulators of multiple types work together nicely 2016-10-24 02:36:35 +02:00
Julian Eisel
54327bf6f1 Some cleanups/refactors for transform manipulators 2016-10-24 01:39:48 +02:00
Julian Eisel
74e784b3e5 Add missing file 2016-10-23 23:37:27 +02:00
Julian Eisel
246a104dbc Implement new resize manipulators 2016-10-23 23:33:18 +02:00
Julian Eisel
c5c2c3be98 Use more modern OpenGL for dial manipulator drawing
Added a new shader for drawing with clipping plane.
2016-10-22 03:18:28 +02:00
Julian Eisel
6e8a0047d6 Merge branch 'blender2.8' into transform-manipulators 2016-10-22 00:31:44 +02:00
Julian Eisel
a14d7f3009 Implement new rotation manipulators 2016-10-21 01:57:40 +02:00
Julian Eisel
57d6983f52 Add view aligned circle manipulator for free translation 2016-10-21 00:51:54 +02:00
Julian Eisel
ca10cacf6c Remove unused includes 2016-10-20 22:14:34 +02:00
Julian Eisel
693265e1e9 Use more modern OpenGL for arrow manipulator drawing
Could/should do hings like sharing VBOs between manipulators, using own shader, use GPU_matrix API, etc but would need to figure out requirements some more first.
2016-10-20 22:11:28 +02:00
Julian Eisel
26de2b4f9c Get tranform manipulators type toggle to work; increase arrow line-width; cleanup 2016-10-20 16:45:38 +02:00
Julian Eisel
8d8f2e2e33 Support drawing arrow manipulators while translating 2016-10-20 02:04:58 +02:00
Julian Eisel
b574bd6cf7 Finish basic transform manipulators for translate 2016-10-20 01:18:30 +02:00
Julian Eisel
91fc0c4f2a Initial implementation of a new transform manipulator
This commit adds the basic framework for the new transform manipulators and also includes working manipulators for translation.

Wasn't really happy with the new transform manipulators code in the custom-manipulators (used to be wiggly-widgets) branch, especially since it reused quite some code of the old manipulator which is messy as hell. I decided to refactor this code by rewriting it from scratch. I'm doing this in an own branch so it can easily be merged into blender 2.8 when ready.

The new transform manipulators are part of the space_view3d module, IMHO they fit better into this than into transform module.
2016-10-19 00:44:40 +02:00
61 changed files with 2254 additions and 2381 deletions

View File

@@ -116,7 +116,7 @@ bool BKE_object_obdata_is_libdata(struct Object *ob);
void BKE_object_obdata_size_init(struct Object *ob, const float scale);
void BKE_object_scale_to_mat3(struct Object *ob, float mat[3][3]);
void BKE_object_rot_to_mat3(struct Object *ob, float mat[3][3], bool use_drot);
void BKE_object_rot_to_mat3(const struct Object *ob, float mat[3][3], bool use_drot);
void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], bool use_compat);
void BKE_object_to_mat3(struct Object *ob, float mat[3][3]);
void BKE_object_to_mat4(struct Object *ob, float mat[4][4]);

View File

@@ -308,8 +308,8 @@ unsigned int BKE_screen_view3d_layer_all(const struct bScreen *sc) ATTR_WARN_UNU
void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene);
void BKE_screen_view3d_scene_sync(struct bScreen *sc);
void BKE_screen_view3d_main_sync(ListBase *screen_lb, struct Scene *scene);
void BKE_screen_view3d_twmode_remove(struct View3D *v3d, const int i);
void BKE_screen_view3d_main_twmode_remove(ListBase *screen_lb, struct Scene *scene, const int i);
void BKE_screen_view3d_transform_orientation_remove(struct View3D *v3d, const int i);
void BKE_screen_view3d_main_transform_orientation_remove(ListBase *screen_lb, struct Scene *scene, const int i);
void BKE_screen_gpu_fx_validate(struct GPUFXSettings *fx_settings);
/* zoom factor conversion */

View File

@@ -451,10 +451,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
}
/* derive the rotation from the average normal:
* - code taken from transform_manipulator.c,
* calc_manipulator_stats, V3D_MANIP_NORMAL case
*/
/* derive the rotation from the average normal */
/* we need the transpose of the inverse for a normal... */
copy_m3_m4(imat, ob->obmat);

View File

@@ -1483,7 +1483,7 @@ void BKE_object_scale_to_mat3(Object *ob, float mat[3][3])
size_to_mat3(mat, vec);
}
void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], bool use_drot)
void BKE_object_rot_to_mat3(const Object *ob, float r_mat[3][3], bool use_drot)
{
float rmat[3][3], dmat[3][3];
@@ -1515,9 +1515,9 @@ void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], bool use_drot)
/* combine these rotations */
if (use_drot)
mul_m3_m3m3(mat, dmat, rmat);
mul_m3_m3m3(r_mat, dmat, rmat);
else
copy_m3_m3(mat, rmat);
copy_m3_m3(r_mat, rmat);
}
void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], bool use_compat)

View File

@@ -629,18 +629,18 @@ void BKE_screen_view3d_main_sync(ListBase *screen_lb, Scene *scene)
}
}
void BKE_screen_view3d_twmode_remove(View3D *v3d, const int i)
void BKE_screen_view3d_transform_orientation_remove(View3D *v3d, const int i)
{
const int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
const int selected_index = (v3d->transform_orientation - V3D_TRANS_ORIENTATION_CUSTOM);
if (selected_index == i) {
v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
v3d->transform_orientation = V3D_TRANS_ORIENTATION_GLOBAL; /* fallback to global */
}
else if (selected_index > i) {
v3d->twmode--;
v3d->transform_orientation--;
}
}
void BKE_screen_view3d_main_twmode_remove(ListBase *screen_lb, Scene *scene, const int i)
void BKE_screen_view3d_main_transform_orientation_remove(ListBase *screen_lb, Scene *scene, const int i)
{
bScreen *sc;
@@ -652,7 +652,7 @@ void BKE_screen_view3d_main_twmode_remove(ListBase *screen_lb, Scene *scene, con
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
View3D *v3d = (View3D *)sl;
BKE_screen_view3d_twmode_remove(v3d, i);
BKE_screen_view3d_transform_orientation_remove(v3d, i);
}
}
}

View File

@@ -7109,8 +7109,8 @@ void blo_do_versions_view3d_split_250(View3D *v3d, ListBase *regions)
}
/* this was not initialized correct always */
if (v3d->twtype == 0)
v3d->twtype = V3D_MANIP_TRANSLATE;
if (v3d->transform_manipulators_type == 0)
v3d->transform_manipulators_type = V3D_MANIP_TRANSLATE;
if (v3d->gridsubdiv == 0)
v3d->gridsubdiv = 10;
}

View File

@@ -1633,6 +1633,23 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
{
/* New transform manipulators */
if (!DNA_struct_elem_find(fd->filesdna, "View3D", "char", "transform_manipulators_type")) {
for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
/* handle pushed-back space data first */
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
View3D *v3d = (View3D *)sl;
v3d->flag3 |= V3D_USE_TRANSFORM_MANIPULATORS;
}
}
}
}
}
}
}
void do_versions_after_linking_270(Main *main)

View File

@@ -1880,8 +1880,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
View3D *v3d = (View3D *) sl;
if (v3d->twtype == 0)
v3d->twtype = V3D_MANIP_TRANSLATE;
if (v3d->transform_manipulators_type == 0)
v3d->transform_manipulators_type = V3D_MANIP_TRANSLATE;
}
}
}

View File

@@ -43,6 +43,7 @@ set(INC
../editors/space_view3d
../render/extern/include
../render/intern/include
../windowmanager
../../../intern/glew-mx
../../../intern/guardedalloc

View File

@@ -48,6 +48,9 @@
#include "DRW_render.h"
#include "WM_api.h"
#include "WM_types.h"
#include "view3d_intern.h"
#include "draw_view.h"
@@ -697,7 +700,8 @@ void DRW_draw_cursor(void)
void DRW_draw_manipulator(void)
{
const bContext *C = DRW_get_context();
ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
v3d->zbuf = false;
BIF_draw_manipulator(C);
WM_manipulatormap_draw(region->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
}

View File

@@ -61,6 +61,20 @@ void imm_draw_lined_circle(unsigned pos, float x, float y, float radius, int nse
/* use this version when VertexFormat has a vec3 position */
void imm_draw_lined_circle_3D(unsigned pos, float x, float y, float radius, int nsegments);
void imm_draw_filled_circle_3D(unsigned pos, float x, float y, float rad, int nsegments);
/**
* Draw a filled arc with the given \a radius,
* starting at angle \a start and arcing through
* \a angle. The arc is centered at the origin
* and drawn in the XY plane.
*
* \param start The initial angle (in radians).
* \param angle The length of the arc (in radians).
* \param radius The arc radius.
* \param nsegments The number of segments to use in drawing the arc.
*/
void imm_draw_filled_arc_3D(unsigned int pos, float start, float angle, float radius, int nsegments);
/**
* Draw a filled circle with the given \a radius.

View File

@@ -102,12 +102,6 @@ enum TfmMode {
#define CTX_PAINT_CURVE (1 << 8)
#define CTX_GPENCIL_STROKES (1 << 9)
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
* (if 0 is returns, *vec is unmodified)
* */
bool calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2]);
struct TransInfo;
struct BaseLegacy;
struct Scene;
@@ -130,7 +124,15 @@ void BIF_createTransformOrientation(struct bContext *C, struct ReportList *repor
void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts);
void BIF_selectTransformOrientationValue(struct bContext *C, int orientation);
void ED_getTransformOrientationMatrix(const struct bContext *C, float orientation_mat[3][3], const short around);
void ED_getLocalTransformOrientationMatrix(const struct bContext *C, float orientation_mat[3][3], const short around);
void ED_getTransformOrientationMatrix(
const struct bContext *C, const char orientation_type, const short around,
float r_orientation_mat[3][3]);
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
* (if 0 is returns, *vec is unmodified)
* */
bool ED_calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2]);
int BIF_countTransformOrientation(const struct bContext *C);
@@ -152,11 +154,6 @@ int BIF_countTransformOrientation(const struct bContext *C);
void Transform_Properties(struct wmOperatorType *ot, int flags);
/* view3d manipulators */
int BIF_do_manipulator(struct bContext *C, const struct wmEvent *event, struct wmOperator *op);
void BIF_draw_manipulator(const struct bContext *C);
/* Snapping */
typedef enum SnapSelect {

View File

@@ -39,6 +39,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
#include "BLI_blenlib.h"
@@ -864,9 +865,9 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tui.wcol_tooltip.text, 255, 255, 255, 255);
rgba_char_args_set_fl(btheme->tui.widget_emboss, 1.0f, 1.0f, 1.0f, 0.02f);
rgba_char_args_set(btheme->tui.xaxis, 220, 0, 0, 255);
rgba_char_args_set(btheme->tui.yaxis, 0, 220, 0, 255);
rgba_char_args_set(btheme->tui.zaxis, 0, 0, 220, 255);
rgba_char_args_set_fl(btheme->tui.xaxis, 1.0f, 0.27f, 0.27f, 1.0f); /* red */
rgba_char_args_set_fl(btheme->tui.yaxis, 0.27f, 1.0f, 0.27f, 1.0f); /* green */
rgba_char_args_set_fl(btheme->tui.zaxis, 0.27f, 0.27f, 1.0f, 1.0f); /* blue */
btheme->tui.menu_shadow_fac = 0.5f;
btheme->tui.menu_shadow_width = 12;
@@ -2396,16 +2397,6 @@ void init_userdef_do_versions(void)
rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255);
}
}
if (!USER_VERSION_ATLEAST(264, 9)) {
bTheme *btheme;
for (btheme = U.themes.first; btheme; btheme = btheme->next) {
rgba_char_args_set(btheme->tui.xaxis, 220, 0, 0, 255);
rgba_char_args_set(btheme->tui.yaxis, 0, 220, 0, 255);
rgba_char_args_set(btheme->tui.zaxis, 0, 0, 220, 255);
}
}
if (!USER_VERSION_ATLEAST(267, 0)) {
/* Freestyle color settings */
@@ -2857,14 +2848,6 @@ void init_userdef_do_versions(void)
}
}
if (!USER_VERSION_ATLEAST(278, 3)) {
for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
/* Keyframe Indicators (were using wrong alpha) */
btheme->tv3d.time_keyframe[3] = btheme->tv3d.time_gp_keyframe[3] = 255;
btheme->ttime.time_keyframe[3] = btheme->ttime.time_gp_keyframe[3] = 255;
}
}
/**
* Include next version bump.
*
@@ -2888,6 +2871,14 @@ void init_userdef_do_versions(void)
for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
btheme->tui.wcol_tab = wcol_tab;
}
for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
rgba_char_args_set_fl(btheme->tui.xaxis, 1.0f, 0.27f, 0.27f, 1.0f); /* red */
rgba_char_args_set_fl(btheme->tui.yaxis, 0.27f, 1.0f, 0.27f, 1.0f); /* green */
rgba_char_args_set_fl(btheme->tui.zaxis, 0.27f, 0.27f, 1.0f, 1.0f); /* blue */
}
/* Flag value has changed */
U.tw_flag = V3D_USE_TRANSFORM_MANIPULATORS;
}
if (U.pixelsize == 0.0f)

View File

@@ -88,7 +88,7 @@ typedef struct {
float mcenter[2];
BMBackup mesh_backup;
void *draw_handle_pixel;
short twtype;
short transform_manipulators_type;
short value_mode; /* Which value does mouse movement and numeric input affect? */
float segments; /* Segments as float so smooth mouse pan works in small increments */
} BevelData;
@@ -176,8 +176,8 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
G.moving = G_TRANSFORM_EDIT;
if (v3d) {
opdata->twtype = v3d->twtype;
v3d->twtype = 0;
opdata->transform_manipulators_type = v3d->transform_manipulators_type;
v3d->transform_manipulators_type = 0;
}
}
@@ -250,7 +250,7 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op)
EDBM_redo_state_free(&opdata->mesh_backup, NULL, false);
ED_region_draw_cb_exit(ar->type, opdata->draw_handle_pixel);
if (v3d) {
v3d->twtype = opdata->twtype;
v3d->transform_manipulators_type = opdata->transform_manipulators_type;
}
G.moving = 0;
}
@@ -329,7 +329,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
opdata = op->customdata;
/* initialize mouse values */
if (!calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, opdata->mcenter)) {
if (!ED_calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, opdata->mcenter)) {
/* in this case the tool will likely do nothing,
* ideally this will never happen and should be checked for above */
opdata->mcenter[0] = opdata->mcenter[1] = 0;

View File

@@ -62,7 +62,7 @@ typedef struct {
/* modal only */
BMBackup mesh_backup;
bool is_first;
short twtype;
short transform_manipulators_type;
} BisectData;
static bool mesh_bisect_interactive_calc(
@@ -148,8 +148,8 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* misc other vars */
G.moving = G_TRANSFORM_EDIT;
opdata->twtype = v3d->twtype;
v3d->twtype = 0;
opdata->transform_manipulators_type = v3d->transform_manipulators_type;
v3d->transform_manipulators_type = 0;
/* initialize modal callout */
ED_area_headerprint(CTX_wm_area(C), IFACE_("LMB: Click and drag to draw cut line"));
@@ -161,7 +161,7 @@ static void edbm_bisect_exit(bContext *C, BisectData *opdata)
{
View3D *v3d = CTX_wm_view3d(C);
EDBM_redo_state_free(&opdata->mesh_backup, NULL, false);
v3d->twtype = opdata->twtype;
v3d->transform_manipulators_type = opdata->transform_manipulators_type;
G.moving = 0;
}

View File

@@ -144,8 +144,8 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal)
opdata->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL);
G.moving = G_TRANSFORM_EDIT;
if (v3d) {
opdata->twtype = v3d->twtype;
v3d->twtype = 0;
opdata->twtype = v3d->transform_manipulators_type;
v3d->transform_manipulators_type = 0;
}
}
@@ -165,7 +165,7 @@ static void edbm_inset_exit(bContext *C, wmOperator *op)
EDBM_redo_state_free(&opdata->mesh_backup, NULL, false);
ED_region_draw_cb_exit(ar->type, opdata->draw_handle_pixel);
if (v3d) {
v3d->twtype = opdata->twtype;
v3d->transform_manipulators_type = opdata->twtype;
}
G.moving = 0;
}
@@ -284,7 +284,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, const wmEvent *event)
opdata = op->customdata;
/* initialize mouse values */
if (!calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, opdata->mcenter)) {
if (!ED_calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, opdata->mcenter)) {
/* in this case the tool will likely do nothing,
* ideally this will never happen and should be checked for above */
opdata->mcenter[0] = opdata->mcenter[1] = 0;

View File

@@ -137,23 +137,6 @@ static void keymap_particle(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
/* Shift+LMB behavior first, so it has priority over KM_ANY item below. */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", true);
RNA_boolean_set(kmi->ptr, "use_planar_constraint", true);
RNA_boolean_set(kmi->ptr, "use_accurate", false);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", true);
RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
RNA_boolean_set(kmi->ptr, "use_accurate", true);
/* Using KM_ANY here to allow holding modifiers before starting to transform. */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", true);
RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
RNA_boolean_set(kmi->ptr, "use_accurate", false);
WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);

View File

@@ -124,26 +124,46 @@ static void imm_draw_disk_partial(
immEnd();
}
/**
* Replacement for gluPartialDisk, (without 'loops' argument).
*/
void imm_draw_filled_disk_partial(
unsigned pos, float x, float y,
float rad_inner, float rad_outer, int nsegments, float start, float sweep)
static void imm_draw_circle_3D(GLenum prim_type, unsigned pos, float x, float y, float rad, int nsegments)
{
imm_draw_disk_partial(PRIM_TRIANGLE_STRIP, pos, x, y, rad_inner, rad_outer, nsegments, start, sweep);
immBegin(prim_type, nsegments);
for (int i = 0; i < nsegments; ++i) {
float angle = 2 * M_PI * ((float)i / (float)nsegments);
immVertex3f(pos, x + rad * cosf(angle),
y + rad * sinf(angle), 0.0f);
}
immEnd();
}
void imm_draw_lined_circle_3D(unsigned pos, float x, float y, float rad, int nsegments)
{
immBegin(PRIM_LINE_LOOP, nsegments);
for (int i = 0; i < nsegments; ++i) {
float angle = 2 * M_PI * ((float)i / (float)nsegments);
immVertex3f(pos, x + rad * cosf(angle), y + rad * sinf(angle), 0.0f);
imm_draw_circle_3D(PRIM_LINE_LOOP, pos, x, y, rad, nsegments);
}
void imm_draw_filled_circle_3D(unsigned pos, float x, float y, float rad, int nsegments)
{
imm_draw_circle_3D(PRIM_TRIANGLE_FAN, pos, x, y, rad, nsegments);
}
static void imm_draw_arc_3D(GLenum prim_type, unsigned int pos, float start, float angle, float radius, int nsegments)
{
immBegin(prim_type, nsegments + 1);
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
for (int i = 0; i < nsegments; i++) {
float t = (float) i / (nsegments - 1);
float cur = start + t * angle;
immVertex3f(pos, cosf(cur) * radius, sinf(cur) * radius, 0.0f);
}
immEnd();
}
void imm_draw_filled_arc_3D(unsigned int pos, float start, float angle, float radius, int nsegments)
{
imm_draw_arc_3D(PRIM_TRIANGLE_FAN, pos, start, angle, radius, nsegments);
}
void imm_draw_line_box(unsigned pos, float x1, float y1, float x2, float y2)
{
immBegin(PRIM_LINE_LOOP, 4);

View File

@@ -65,6 +65,7 @@ set(SRC
view3d_select.c
view3d_snap.c
view3d_toolbar.c
view3d_transform_manipulators.c
view3d_view.c
view3d_intern.h

View File

@@ -336,13 +336,13 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->flag = V3D_SELECT_OUTLINE;
v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL;
v3d->flag3 |= (U.tw_flag & V3D_USE_TRANSFORM_MANIPULATORS);
v3d->lens = 35.0f;
v3d->near = 0.01f;
v3d->far = 1000.0f;
v3d->twflag |= U.tw_flag & V3D_USE_MANIPULATOR;
v3d->twtype = V3D_MANIP_TRANSLATE;
v3d->transform_manipulators_type = V3D_MANIP_TRANSLATE;
v3d->around = V3D_AROUND_CENTER_MEAN;
v3d->bundle_size = 0.2f;
@@ -488,6 +488,12 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
ListBase *lb;
wmKeyMap *keymap;
if (!ar->manipulator_map) {
ar->manipulator_map = WM_manipulatormap_new_from_type(&(const struct wmManipulatorMapType_Params) {
"View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW});
}
WM_manipulatormap_add_handlers(ar, ar->manipulator_map);
/* object ops. */
/* important to be before Pose keymap since they can both be enabled at once */
@@ -815,7 +821,8 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
{
Scene *scene = sc->scene;
View3D *v3d = sa->spacedata.first;
wmManipulatorMap *mmap = ar->manipulator_map;
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -841,6 +848,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
if (wmn->reference)
view3d_recalc_used_layers(ar, wmn, wmn->reference);
ED_region_tag_redraw(ar);
WM_manipulatormap_tag_refresh(mmap);
break;
case ND_FRAME:
case ND_TRANSFORM:
@@ -852,6 +860,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_MARKERS:
case ND_MODE:
ED_region_tag_redraw(ar);
WM_manipulatormap_tag_refresh(mmap);
break;
case ND_WORLD:
/* handled by space_view3d_listener() for v3d access */
@@ -884,6 +893,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case ND_POINTCACHE:
case ND_LOD:
ED_region_tag_redraw(ar);
WM_manipulatormap_tag_refresh(mmap);
break;
}
switch (wmn->action) {
@@ -906,6 +916,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
}
case ND_DATA:
case ND_VERTEX_GROUP:
WM_manipulatormap_tag_refresh(mmap);
ED_region_tag_redraw(ar);
break;
}
@@ -1002,6 +1013,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
}
ED_region_tag_redraw(ar);
WM_manipulatormap_tag_refresh(mmap);
}
break;
case NC_ID:
@@ -1031,6 +1043,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
case NC_GPENCIL:
if (wmn->data == ND_DATA || ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
ED_region_tag_redraw(ar);
WM_manipulatormap_tag_refresh(mmap);
}
break;
}
@@ -1376,6 +1389,14 @@ static void view3d_id_remap(ScrArea *sa, SpaceLink *slink, ID *old_id, ID *new_i
}
}
static void view3d_manipulators(void)
{
wmManipulatorMapType *mmaptype = WM_manipulatormaptype_ensure(&(const struct wmManipulatorMapType_Params) {
"View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW});
WM_manipulatorgrouptype_append(mmaptype, VIEW3D_MGT_transform_manipulators);
}
/* only called once, from space/spacetypes.c */
void ED_spacetype_view3d(void)
{
@@ -1395,6 +1416,7 @@ void ED_spacetype_view3d(void)
st->dropboxes = view3d_dropboxes;
st->context = view3d_context;
st->id_remap = view3d_id_remap;
st->manipulators = view3d_manipulators;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d main region");

View File

@@ -83,6 +83,7 @@
#include "RE_engine.h"
#include "WM_api.h"
#include "WM_types.h"
#include "view3d_intern.h" /* own include */
@@ -2211,11 +2212,14 @@ static void view3d_draw_reference_images(const bContext *UNUSED(C))
/**
* 3D manipulators
*/
static void view3d_draw_manipulator(const bContext *C)
static void view3d_draw_manipulators(const bContext *C, const ARegion *ar)
{
View3D *v3d = CTX_wm_view3d(C);
v3d->zbuf = false;
BIF_draw_manipulator(C);
/* TODO, only draws 3D manipulators right now, need to see how 2D drawing will work in new viewport */
/* draw depth culled manipulators - manipulators need to be updated *after* view matrix was set up */
/* TODO depth culling manipulators is not yet supported, just drawing _3D here, should
* later become _IN_SCENE (and draw _3D separate) */
WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
}
/**
@@ -2308,7 +2312,8 @@ static void view3d_draw_view(const bContext *C, ARegion *ar, DrawData *draw_data
view3d_draw_other_elements(C, ar);
view3d_draw_tool_ui(C);
view3d_draw_reference_images(C);
view3d_draw_manipulator(C);
view3d_draw_manipulators(C, ar);
view3d_draw_region_info(C, ar);
gpuMatrixEnd();

View File

@@ -79,6 +79,7 @@
#include "BIF_glutil.h"
#include "WM_api.h"
#include "WM_types.h"
#include "BLF_api.h"
#include "BLT_translation.h"
@@ -1708,10 +1709,6 @@ static void view3d_draw_objects(
view3d_draw_bgpic_test(scene, ar, v3d, true, do_camera_frame);
}
if (!draw_offscreen) {
BIF_draw_manipulator(C);
}
/* cleanup */
if (v3d->zbuf) {
v3d->zbuf = false;
@@ -2428,6 +2425,11 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Sce
/* main drawing call */
view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
/* draw depth culled manipulators - manipulators need to be updated *after* view matrix was set up */
/* TODO depth culling manipulators is not yet supported, just drawing _3D here, should
* later become _IN_SCENE (and draw _3D separate) */
WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
/* post process */
if (do_compositing) {
GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);

View File

@@ -623,7 +623,7 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
Object *ob_act = OBACT_NEW;
if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
/* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
/* with weight-paint + pose-mode, fall through to using ED_calculateTransformCenter */
((ob_act->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(ob_act)) == 0)
{
/* in case of sculpting use last average stroke position as a rotation
@@ -689,7 +689,7 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
}
else {
/* If there's no selection, lastofs is unmodified and last value since static */
is_set = calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, lastofs, NULL);
is_set = ED_calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, lastofs, NULL);
}
copy_v3_v3(r_dyn_ofs, lastofs);
@@ -3790,7 +3790,7 @@ static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar,
float twmat[3][3];
/* same as transform manipulator when normal is set */
ED_getTransformOrientationMatrix(C, twmat, V3D_AROUND_ACTIVE);
ED_getLocalTransformOrientationMatrix(C, twmat, V3D_AROUND_ACTIVE);
mat3_to_quat(obact_quat, twmat);
invert_qt_normalized(obact_quat);
@@ -4748,57 +4748,18 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
/* ***************** manipulator op ******************* */
static int manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
if (!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
/* note; otherwise opengl won't work */
view3d_operator_needs_opengl(C);
if (BIF_do_manipulator(C, event, op) == 0)
return OPERATOR_PASS_THROUGH;
return OPERATOR_FINISHED;
}
void VIEW3D_OT_manipulator(wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "3D Manipulator";
ot->description = "Manipulate selected item by axis";
ot->idname = "VIEW3D_OT_manipulator";
/* api callbacks */
ot->invoke = manipulator_invoke;
ot->poll = ED_operator_view3d_active;
/* properties to pass to transform */
Transform_Properties(ot, P_CONSTRAINT);
prop = RNA_def_boolean(ot->srna, "use_planar_constraint", false, "Planar Constraint", "Limit the transformation to the "
"two axes that have not been clicked (translate/scale only)");
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
static int enable_manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
v3d->twtype = 0;
v3d->transform_manipulators_type = 0;
if (RNA_boolean_get(op->ptr, "translate"))
v3d->twtype |= V3D_MANIP_TRANSLATE;
v3d->transform_manipulators_type |= V3D_MANIP_TRANSLATE;
if (RNA_boolean_get(op->ptr, "rotate"))
v3d->twtype |= V3D_MANIP_ROTATE;
v3d->transform_manipulators_type |= V3D_MANIP_ROTATE;
if (RNA_boolean_get(op->ptr, "scale"))
v3d->twtype |= V3D_MANIP_SCALE;
v3d->transform_manipulators_type |= V3D_MANIP_SCALE;
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);

View File

@@ -367,8 +367,8 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
/* Transform widget / manipulators */
row = uiLayoutRow(layout, true);
uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
if (v3d->twflag & V3D_USE_MANIPULATOR) {
uiItemR(row, &v3dptr, "transform_manipulators", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
if (v3d->flag3 & V3D_USE_TRANSFORM_MANIPULATORS) {
uiItemR(row, &v3dptr, "transform_manipulators_type", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
}
uiItemR(row, &v3dptr, "transform_orientation", 0, "", ICON_NONE);
}

View File

@@ -48,6 +48,7 @@ struct bMotionPath;
struct bPoseChannel;
struct Mesh;
struct SceneLayer;
struct wmManipulatorGroupType;
struct wmOperatorType;
struct wmWindowManager;
struct wmKeyConfig;
@@ -101,7 +102,6 @@ void VIEW3D_OT_view_orbit(struct wmOperatorType *ot);
void VIEW3D_OT_view_roll(struct wmOperatorType *ot);
void VIEW3D_OT_clip_border(struct wmOperatorType *ot);
void VIEW3D_OT_cursor3d(struct wmOperatorType *ot);
void VIEW3D_OT_manipulator(struct wmOperatorType *ot);
void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot);
void VIEW3D_OT_render_border(struct wmOperatorType *ot);
void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot);
@@ -351,4 +351,8 @@ void VP_drawrenderborder(ARegion *ar, View3D *v3d);
void VP_view3d_draw_background_none(void);
void VP_view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv3d);
/* manipulators */
void VIEW3D_MGT_transform_manipulators(struct wmManipulatorGroupType *mgt);
#endif /* __VIEW3D_INTERN_H__ */

View File

@@ -193,7 +193,6 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_render_border);
WM_operatortype_append(VIEW3D_OT_clear_render_border);
WM_operatortype_append(VIEW3D_OT_zoom_border);
WM_operatortype_append(VIEW3D_OT_manipulator);
WM_operatortype_append(VIEW3D_OT_enable_manipulator);
WM_operatortype_append(VIEW3D_OT_cursor3d);
WM_operatortype_append(VIEW3D_OT_select_lasso);
@@ -240,23 +239,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
/* only for region 3D window */
keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0);
/* Shift+LMB behavior first, so it has priority over KM_ANY item below. */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", true);
RNA_boolean_set(kmi->ptr, "use_planar_constraint", true);
RNA_boolean_set(kmi->ptr, "use_accurate", false);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", true);
RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
RNA_boolean_set(kmi->ptr, "use_accurate", true);
/* Using KM_ANY here to allow holding modifiers before starting to transform. */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", true);
RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
RNA_boolean_set(kmi->ptr, "use_accurate", false);
WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_rotate", MIDDLEMOUSE, KM_PRESS, 0, 0);

View File

@@ -0,0 +1,794 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/editors/space_view3d/view3d_transform_manipulators.c
* \ingroup spview3d
*/
#include "BLI_math.h"
#include "BKE_action.h"
#include "BKE_context.h"
#include "BKE_object.h"
#include "DNA_armature_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
#include "ED_armature.h"
#include "ED_transform.h"
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "UI_resources.h"
#include "view3d_intern.h"
#include "WM_api.h"
#include "WM_types.h"
/* threshold for testing view aligned axis manipulator */
#define TRANSFORM_MAN_AXIS_DOT_MIN 0.02f
#define TRANSFORM_MAN_AXIS_DOT_MAX 0.1f
#define TRANSFORM_MAN_AXIS_LINE_WIDTH 2.0f
/**
* Transform axis type that can be used as index.
*/
typedef enum eTransformAxisType {
/* single axes */
TRANSFORM_AXIS_X = 0,
TRANSFORM_AXIS_Y = 1,
TRANSFORM_AXIS_Z = 2,
/* mulitple axes */
TRANSFORM_AXIS_VIEW = 3,
TRANSFORM_AXIS_XY = 4,
TRANSFORM_AXIS_YZ = 5,
TRANSFORM_AXIS_ZX = 6,
} eTransformAxisType;
/**
* Struct for carrying data of transform manipulators as wmManipulatorGroup.customdata.
*/
typedef struct TransformManipulatorsInfo {
struct TransformAxisManipulator *axes; /* Array of axes */
float mat[4][4]; /* Cached loc/rot matrix */
float init_rot[3][3]; /* rotation matrix since last transform (to calculate rotation delta while dragging) */
} TransformManipulatorsInfo;
/* Callback types */
typedef wmManipulator *TransformManipulatorInitFunc(struct TransformAxisManipulator *, wmManipulatorGroup *mgroup);
typedef void TransformManipulatorUpdateFunc(
const bContext *, const TransformManipulatorsInfo *, const struct TransformAxisManipulator *);
typedef int TransformManipulatorHanderFunc(bContext *, const wmEvent *, wmManipulator *, const int);
/**
* Struct that allows us to store info for each transform axis manipulator in a rather generic way.
*/
typedef struct TransformAxisManipulator {
/* -- initialized using static array -- */
eTransformAxisType type;
int transform_type; /* View3d->twtype */
/* per-manipulator callbacks for initializing/updating data */
TransformManipulatorInitFunc (*init);
TransformManipulatorUpdateFunc (*refresh);
TransformManipulatorUpdateFunc (*draw_prepare);
TransformManipulatorHanderFunc (*handler);
const char *name;
int constraint[3]; /* {x, y, z} */
int protectflag; /* the protectflags this axis checks (e.g. OB_LOCK_LOCZ) */
/* appearance */
float scale;
float line_width;
int theme_colorid;
int manipulator_style;
/* The manipulator that represents this axis */
wmManipulator *manipulator;
} TransformAxisManipulator;
/* -------------------------------------------------------------------- */
/* Manipulator init/update callbacks */
static wmManipulator *manipulator_arrow_init(TransformAxisManipulator *axis, wmManipulatorGroup *mgroup)
{
return WM_arrow_manipulator_new(mgroup, axis->name, axis->manipulator_style);
}
static wmManipulator *manipulator_dial_init(TransformAxisManipulator *axis, wmManipulatorGroup *mgroup)
{
wmManipulator *manipulator = WM_dial_manipulator_new(mgroup, axis->name, axis->manipulator_style);
if (axis->transform_type == V3D_MANIP_ROTATE) { /* could also be separate callback */
WM_manipulator_set_flag(manipulator, WM_MANIPULATOR_DRAW_ACTIVE, true);
}
return manipulator;
}
/**
* Sets up \a r_start and \a r_len to define arrow line range.
* Needed to adjust line drawing for combined manipulator axis types.
*/
static void manipulator_line_range(
const TransformAxisManipulator *axis, const View3D *v3d,
float *r_start, float *r_len)
{
const float ofs = 0.2f;
*r_start = 0.2f;
*r_len = 1.0f;
switch (axis->transform_type) {
case V3D_MANIP_TRANSLATE:
if (v3d->transform_manipulators_type & V3D_MANIP_SCALE) {
*r_start = *r_len - ofs + 0.075f;
}
if (v3d->transform_manipulators_type & V3D_MANIP_ROTATE) {
*r_len += ofs;
}
break;
case V3D_MANIP_SCALE:
if (v3d->transform_manipulators_type & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE)) {
*r_len -= ofs + 0.025f;
}
break;
}
*r_len -= *r_start;
}
static void manipulator_arrow_update_line_range(const View3D *v3d, const TransformAxisManipulator *axis)
{
float start[3] = {0.0f};
float len;
manipulator_line_range(axis, v3d, &start[2], &len);
WM_manipulator_set_offset(axis->manipulator, start);
WM_arrow_manipulator_set_length(axis->manipulator, len);
}
static void manipulator_arrow_refresh(
const bContext *C, const TransformManipulatorsInfo *UNUSED(info), const TransformAxisManipulator *axis)
{
manipulator_arrow_update_line_range(CTX_wm_view3d(C), axis);
}
static void manipulator_dial_refresh(
const bContext *UNUSED(C), const TransformManipulatorsInfo *info, const TransformAxisManipulator *axis)
{
WM_dial_manipulator_set_up_vector(axis->manipulator, info->mat[axis->type]);
}
static void manipulator_arrow_draw_prepare(
const bContext *UNUSED(C), const TransformManipulatorsInfo *info, const TransformAxisManipulator *axis)
{
WM_arrow_manipulator_set_direction(axis->manipulator, info->mat[axis->type]);
}
static void manipulator_view_dial_draw_prepare(
const bContext *C, const TransformManipulatorsInfo *UNUSED(info), const TransformAxisManipulator *axis)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
WM_dial_manipulator_set_up_vector(axis->manipulator, rv3d->viewinv[2]);
}
/**
* Custom handler for transform manipulators to update them while modal transform operator runs.
*/
static int manipulator_axis_translate_handler(
bContext *C, const wmEvent *UNUSED(event), wmManipulator *manipulator, const int UNUSED(flag))
{
View3D *v3d = CTX_wm_view3d(C);
float origin[3];
/* update origin */
if (ED_calculateTransformCenter((bContext *)C, v3d->around, origin, NULL)) {
WM_manipulator_set_origin(manipulator, origin);
}
return OPERATOR_PASS_THROUGH;
}
static TransformAxisManipulator *transform_axis_manipulator_find(
const TransformManipulatorsInfo *info, const wmManipulator *manipulator)
{
for (int i = 0; info->axes[i].name; i++) {
if (info->axes[i].manipulator == manipulator) {
return &info->axes[i];
}
}
return NULL;
}
static float manipulator_axis_rotate_get_delta_angle(
const RegionView3D *rv3d, const Object *ob,
TransformManipulatorsInfo *info, eTransformAxisType axis_type)
{
const bool is_view_aligned = (axis_type == TRANSFORM_AXIS_VIEW);
float rot[3][3], delta_rot[3][3];
float axis_vec[3];
float delta_angle;
/* Get updated rotation matrix */
BKE_object_rot_to_mat3(ob, rot, true);
/* Calculate delta rotation */
transpose_m3(rot);
mul_m3_m3m3(delta_rot, info->init_rot, rot);
/* convert delta rotation to angle */
mat3_to_axis_angle(axis_vec, &delta_angle, delta_rot);
if (is_view_aligned) {
if (dot_v3v3(axis_vec, rv3d->viewinv[2]) < 0.0f) {
delta_angle *= -1.0f;
}
}
else {
BLI_assert(axis_type < 3);
delta_angle *= axis_vec[axis_type];
}
#if 0
/* TODO Would be nicer if the ghost arc to show current delta rotation value could display the whole 360 degree
* range instead of -180 to 180. This block does this conversion, however it only works nicely when dragging in
* one direction. Other direction will start with full 360 degree arc and substract angle from it. */
if (delta_angle < 0.0f) {
/* convert to pi * 2 range */
delta_angle = (float)M_PI * 2.0f - fabs(delta_angle);
BLI_assert(delta_angle > 0.0f);
}
#endif
return delta_angle;
}
static double manipulator_axis_rotate_angle_to_value(float angle)
{
return (angle / (M_PI * 2.0));
}
static int manipulator_axis_rotate_handler(
bContext *C, const wmEvent *UNUSED(event), wmManipulator *manipulator, const int UNUSED(flag))
{
const RegionView3D *rv3d = CTX_wm_region_view3d(C);
const wmManipulatorGroup *mgroup = WM_manipulator_get_parent_group(manipulator);
TransformManipulatorsInfo *info = mgroup->customdata;
TransformAxisManipulator *axis = transform_axis_manipulator_find(info, manipulator);
const float angle = manipulator_axis_rotate_get_delta_angle(rv3d, CTX_data_active_object(C), info, axis->type);
const double value = manipulator_axis_rotate_angle_to_value(angle);
WM_dial_manipulator_set_value(manipulator, value);
return OPERATOR_PASS_THROUGH;
}
/* -------------------------------------------------------------------- */
/* General helpers */
/**
* This TransformAxisManipulator array contains all the info we need to initialize, store and identify all
* transform manipulators. When creating a new group instance we simply create an allocated version of this.
*
* \note Order matches drawing order!
*/
static TransformAxisManipulator tman_axes[] = {
{
TRANSFORM_AXIS_X, V3D_MANIP_TRANSLATE,
manipulator_arrow_init,
manipulator_arrow_refresh,
manipulator_arrow_draw_prepare,
manipulator_axis_translate_handler,
"translate_x", {1, 0, 0}, OB_LOCK_LOCX,
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_X, MANIPULATOR_ARROW_STYLE_CONE,
},
{
TRANSFORM_AXIS_Y, V3D_MANIP_TRANSLATE,
manipulator_arrow_init,
manipulator_arrow_refresh,
manipulator_arrow_draw_prepare,
manipulator_axis_translate_handler,
"translate_y", {0, 1, 0}, OB_LOCK_LOCY,
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_Y, MANIPULATOR_ARROW_STYLE_CONE,
},
{
TRANSFORM_AXIS_Z, V3D_MANIP_TRANSLATE,
manipulator_arrow_init,
manipulator_arrow_refresh,
manipulator_arrow_draw_prepare,
manipulator_axis_translate_handler,
"translate_z", {0, 0, 1}, OB_LOCK_LOCZ,
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_Z, MANIPULATOR_ARROW_STYLE_CONE,
},
{
TRANSFORM_AXIS_VIEW, V3D_MANIP_TRANSLATE,
manipulator_dial_init,
manipulator_dial_refresh,
manipulator_view_dial_draw_prepare,
NULL,
"translate_view", {0}, 0,
0.2f, TRANSFORM_MAN_AXIS_LINE_WIDTH, -1, MANIPULATOR_DIAL_STYLE_RING,
},
{
TRANSFORM_AXIS_X, V3D_MANIP_ROTATE,
manipulator_dial_init,
manipulator_dial_refresh,
NULL,
manipulator_axis_rotate_handler,
"rotate_x", {1, 0, 0}, OB_LOCK_ROTX,
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH + 1.0f, TH_AXIS_X, MANIPULATOR_DIAL_STYLE_RING_CLIPPED,
},
{
TRANSFORM_AXIS_Y, V3D_MANIP_ROTATE,
manipulator_dial_init,
manipulator_dial_refresh,
NULL,
manipulator_axis_rotate_handler,
"rotate_y", {0, 1, 0}, OB_LOCK_ROTY,
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH + 1.0f, TH_AXIS_Y, MANIPULATOR_DIAL_STYLE_RING_CLIPPED,
},
{
TRANSFORM_AXIS_Z, V3D_MANIP_ROTATE,
manipulator_dial_init,
manipulator_dial_refresh,
NULL,
manipulator_axis_rotate_handler,
"rotate_y", {0, 0, 1}, OB_LOCK_ROTZ,
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH + 1.0f, TH_AXIS_Z, MANIPULATOR_DIAL_STYLE_RING_CLIPPED,
},
{
TRANSFORM_AXIS_VIEW, V3D_MANIP_ROTATE,
manipulator_dial_init,
NULL,
manipulator_view_dial_draw_prepare,
manipulator_axis_rotate_handler,
"rotate_view", {0}, OB_LOCK_ROTZ,
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH + 1.0f, -1, MANIPULATOR_DIAL_STYLE_RING,
},
{
TRANSFORM_AXIS_X, V3D_MANIP_SCALE,
manipulator_arrow_init,
manipulator_arrow_refresh,
manipulator_arrow_draw_prepare,
NULL,
"scale_x", {1, 0, 0}, OB_LOCK_SCALEX,
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_X, MANIPULATOR_ARROW_STYLE_CUBE,
},
{
TRANSFORM_AXIS_Y, V3D_MANIP_SCALE,
manipulator_arrow_init,
manipulator_arrow_refresh,
manipulator_arrow_draw_prepare,
NULL,
"scale_y", {0, 1, 0}, OB_LOCK_SCALEY,
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_Y, MANIPULATOR_ARROW_STYLE_CUBE,
},
{
TRANSFORM_AXIS_Z, V3D_MANIP_SCALE,
manipulator_arrow_init,
manipulator_arrow_refresh,
manipulator_arrow_draw_prepare,
NULL,
"scale_y", {0, 0, 1}, OB_LOCK_SCALEZ,
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_Z, MANIPULATOR_ARROW_STYLE_CUBE,
},
{
TRANSFORM_AXIS_VIEW, V3D_MANIP_SCALE,
manipulator_dial_init,
manipulator_dial_refresh,
manipulator_view_dial_draw_prepare,
NULL,
"scale_view", {0}, 0,
0.2f, TRANSFORM_MAN_AXIS_LINE_WIDTH, -1, MANIPULATOR_DIAL_STYLE_RING,
},
{0, 0, NULL}
};
static void transform_manipulators_info_init(TransformManipulatorsInfo *info)
{
info->axes = MEM_callocN(sizeof(tman_axes), STRINGIFY(TransformAxisManipulator));
memcpy(info->axes, tman_axes, sizeof(tman_axes));
}
static void transform_manipulators_info_free(void *customdata)
{
TransformManipulatorsInfo *info = customdata;
MEM_freeN(info->axes);
MEM_freeN(info);
}
/* -------------------------------------------------------------------- */
/* init callback and helpers */
static const char *transform_axis_ot_name_get(int transform_type)
{
const char *name = NULL;
switch (transform_type) {
case V3D_MANIP_TRANSLATE:
name = "TRANSFORM_OT_translate";
break;
case V3D_MANIP_ROTATE:
name = "TRANSFORM_OT_rotate";
break;
case V3D_MANIP_SCALE:
name = "TRANSFORM_OT_resize";
break;
default:
BLI_assert(0);
break;
}
return name;
}
/**
* Create and initialize a manipulator for \a axis.
*/
static void transform_axis_manipulator_init(TransformAxisManipulator *axis, wmManipulatorGroup *mgroup)
{
axis->manipulator = axis->init(axis, mgroup);
const char *op_name = transform_axis_ot_name_get(axis->transform_type);
PointerRNA *ptr = WM_manipulator_set_operator(axis->manipulator, op_name);
if (axis->handler) {
WM_manipulator_set_custom_handler(axis->manipulator, axis->handler);
}
WM_manipulator_set_scale(axis->manipulator, axis->scale);
WM_manipulator_set_line_width(axis->manipulator, axis->line_width);
if (RNA_struct_find_property(ptr, "constraint_axis")) {
RNA_boolean_set_array(ptr, "constraint_axis", axis->constraint);
}
RNA_boolean_set(ptr, "release_confirm", 1);
RNA_boolean_set(ptr, "draw_helplines", 0);
}
static void transform_manipulatorgroup_init(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
{
TransformManipulatorsInfo *info = MEM_callocN(sizeof(*info), __func__);
transform_manipulators_info_init(info);
for (int i = 0; info->axes[i].name; i++) {
transform_axis_manipulator_init(&info->axes[i], mgroup);
}
mgroup->customdata = info;
mgroup->customdata_free = transform_manipulators_info_free;
}
/* -------------------------------------------------------------------- */
/* refresh callback and helpers */
static bool transform_axis_manipulator_is_visible(TransformAxisManipulator *axis, char transform_type, int protectflag)
{
return ((axis->transform_type & transform_type) &&
(!axis->protectflag || (axis->protectflag & protectflag) != axis->protectflag));
}
static int transform_manipulators_protectflag_posemode_get(Object *ob, View3D *v3d)
{
bPoseChannel *pchan;
int protectflag = 0;
if ((v3d->around == V3D_AROUND_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) {
if (pchan->bone) {
protectflag = pchan->protectflag;
}
}
else {
/* use channels to get stats */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
Bone *bone = pchan->bone;
if (bone && (bone->flag & BONE_TRANSFORM)) {
protectflag |= pchan->protectflag;
}
}
}
return protectflag;
}
static int transform_manipulators_protectflag_editmode_get(Object *obedit, View3D *v3d)
{
int protectflag = 0;
if (obedit->type == OB_ARMATURE) {
const bArmature *arm = obedit->data;
EditBone *ebo;
if ((v3d->around == V3D_AROUND_ACTIVE) && (ebo = arm->act_edbone)) {
if (ebo->flag & BONE_EDITMODE_LOCKED) {
protectflag = (OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE);
}
}
else {
for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
if (EBONE_VISIBLE(arm, ebo)) {
if ((ebo->flag & BONE_SELECTED) && (ebo->flag & BONE_EDITMODE_LOCKED)) {
protectflag = (OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE);
break;
}
}
}
}
}
return protectflag;
}
static int transform_manipulators_protectflag_objectmode_get(const Scene *scene)
{
int protectflag = 0;
for (Base *base = scene->base.first; base; base = base->next) {
if (TESTBASELIB_NEW(base)) {
protectflag |= base->object->protectflag;
}
}
return protectflag;
}
static int transform_manipulators_protectflag_get(const bContext *C, View3D *v3d)
{
Scene *scene = CTX_data_scene(C);
Object *ob = OBACT, *obedit = CTX_data_edit_object(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
const bool is_gp_edit = (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE));
int protectflag = 0;
if (is_gp_edit) {
/* pass */
}
else if (obedit) {
protectflag = transform_manipulators_protectflag_editmode_get(obedit, v3d);
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
protectflag = transform_manipulators_protectflag_posemode_get(ob, v3d);
}
else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
/* pass */
}
else {
protectflag = transform_manipulators_protectflag_objectmode_get(scene);
}
return protectflag;
}
/**
* Get (or calculate if needed) location and rotation for the transform manipulators as
* transformation matrix. This may iterate over entire selection so avoid as many calls as possible!
*
* \return If valid matrix has been created. This is not the case if no selection was found.
*/
static bool transform_manipulators_matrix_get(const bContext *C, const View3D *v3d,
float r_local_rot[3][3], float r_mat[4][4])
{
float origin[3];
float rot[3][3];
if (ED_calculateTransformCenter((bContext *)C, v3d->around, origin, NULL)) {
ED_getTransformOrientationMatrix(C, v3d->transform_orientation, v3d->around, rot);
if (v3d->transform_orientation == V3D_TRANS_ORIENTATION_LOCAL) {
copy_m3_m3(r_local_rot, rot);
}
else {
ED_getTransformOrientationMatrix(C, V3D_TRANS_ORIENTATION_LOCAL, v3d->around, r_local_rot);
}
copy_m4_m3(r_mat, rot);
copy_v3_v3(r_mat[3], origin);
return true;
}
return false;
}
/**
* Performs some additional layer checks, #ED_calculateTransformCenter does the rest of them.
*/
static bool transform_manipulators_layer_visible(const bContext *C, const View3D *v3d)
{
Scene *scene = CTX_data_scene(C);
Object *ob = OBACT;
Object *obedit = CTX_data_edit_object(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
if (is_gp_edit) {
/* TODO */
}
else if (obedit) {
return (obedit->lay & v3d->lay) != 0;
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
return (ob->lay & v3d->lay) != 0;
}
return true;
}
static void transform_manipulatorgroup_refresh(const bContext *C, wmManipulatorGroup *mgroup)
{
View3D *v3d = CTX_wm_view3d(C);
TransformManipulatorsInfo *info = mgroup->customdata;
float mat[4][4], local_rot[3][3];
const bool any_visible = transform_manipulators_layer_visible(C, v3d) &&
transform_manipulators_matrix_get(C, v3d, local_rot, mat);
const int protectflag = transform_manipulators_protectflag_get(C, v3d);
copy_m4_m4(info->mat, mat);
copy_m3_m3(info->init_rot, local_rot);
for (int i = 0; info->axes[i].name; i++) {
TransformAxisManipulator *axis = &info->axes[i];
if (any_visible && transform_axis_manipulator_is_visible(axis, v3d->transform_manipulators_type, protectflag)) {
WM_manipulator_set_flag(axis->manipulator, WM_MANIPULATOR_HIDDEN, false);
}
else {
WM_manipulator_set_flag(axis->manipulator, WM_MANIPULATOR_HIDDEN, true);
continue;
}
WM_manipulator_set_origin(axis->manipulator, mat[3]); /* Could do in callback, but we do it for all anyway */
if (axis->refresh) {
axis->refresh(C, info, axis);
}
}
}
/* -------------------------------------------------------------------- */
/* draw_prepare callback and helpers */
static float transform_axis_view_alpha_fac_get(
const TransformAxisManipulator *axis, const RegionView3D *rv3d, const float mat[4][4])
{
const float dot_min = TRANSFORM_MAN_AXIS_DOT_MIN;
const float dot_max = TRANSFORM_MAN_AXIS_DOT_MAX;
float view_vec[3], axis_vec[3];
float idot[3], idot_axis;
ED_view3d_global_to_vector(rv3d, mat[3], view_vec);
for (int i = 0; i < 3; i++) {
normalize_v3_v3(axis_vec, mat[i]);
idot[i] = 1.0f - fabsf(dot_v3v3(view_vec, axis_vec));
}
idot_axis = idot[axis->type];
return ((idot_axis > dot_max) ?
1.0f : (idot_axis < dot_min) ?
0.0f : ((idot_axis - dot_min) / (dot_max - dot_min)));
}
static void transform_axis_manipulator_set_color(
const TransformAxisManipulator *axis, const RegionView3D *rv3d, const float mat[4][4])
{
/* alpha values for normal/highlighted states */
const float alpha = 0.6f;
const float alpha_hi = 1.0f;
float alpha_fac = 1.0f;
float col[4], col_hi[4];
if (axis->theme_colorid == -1) {
copy_v4_fl(col, 1.0f);
}
else {
UI_GetThemeColor4fv(axis->theme_colorid, col);
alpha_fac = transform_axis_view_alpha_fac_get(axis, rv3d, mat);
}
copy_v4_v4(col_hi, col);
col[3] = alpha * alpha_fac;
col_hi[3] = alpha_hi * alpha_fac;
WM_manipulator_set_colors(axis->manipulator, col, col_hi);
}
/**
* Some transform orientation modes require updating the transform manipulators rotation matrix every redraw.
* \return If manipulators need to update their rotation.
*/
static bool transform_manipulators_draw_rotmatrix_get(const bContext *C, const View3D *v3d, float r_rot[3][3])
{
if (v3d->transform_orientation == V3D_TRANS_ORIENTATION_VIEW) {
ED_getTransformOrientationMatrix(C, v3d->transform_orientation, v3d->around, r_rot);
return true;
}
return false;
}
static void transform_manipulatorgroup_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
{
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
TransformManipulatorsInfo *info = mgroup->customdata;
float rot[3][3];
if (transform_manipulators_draw_rotmatrix_get(C, v3d, rot)) {
copy_m4_m3(info->mat, rot);
}
for (int i = 0; info->axes[i].name; i++) {
if (info->axes[i].draw_prepare) {
info->axes[i].draw_prepare(C, info, &info->axes[i]);
}
transform_axis_manipulator_set_color(&info->axes[i], rv3d, info->mat);
}
}
/* -------------------------------------------------------------------- */
static bool transform_manipulatorgroup_poll(const bContext *C, wmManipulatorGroupType *UNUSED(mgt))
{
const View3D *v3d = CTX_wm_view3d(C);
const Object *ob = CTX_data_active_object(C);
const Object *editob = CTX_data_edit_object(C);
BLI_assert(v3d != NULL);
/* avoiding complex stuff here (like checking for selected vertices),
* this poll check runs on every redraw (and more) */
return (((v3d->flag3 & V3D_USE_TRANSFORM_MANIPULATORS) != 0) &&
((v3d->transform_manipulators_type & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE | V3D_MANIP_SCALE)) != 0) &&
(ob || editob));
}
void VIEW3D_MGT_transform_manipulators(wmManipulatorGroupType *mgt)
{
mgt->name = "Transform Manipulators";
mgt->poll = transform_manipulatorgroup_poll;
mgt->init = transform_manipulatorgroup_init;
mgt->refresh = transform_manipulatorgroup_refresh;
mgt->draw_prepare = transform_manipulatorgroup_draw_prepare;
mgt->flag = (WM_MANIPULATORGROUPTYPE_IS_3D | WM_MANIPULATORGROUPTYPE_SCALE_3D);
}

View File

@@ -45,7 +45,6 @@ set(SRC
transform_conversions.c
transform_generics.c
transform_input.c
transform_manipulator.c
transform_ops.c
transform_orientations.c
transform_snap.c

View File

@@ -928,17 +928,17 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
stopConstraint(t);
}
else {
setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_axis, msg1);
setUserConstraint(t, V3D_TRANS_ORIENTATION_GLOBAL, constraint_axis, msg1);
}
}
else if (!edit_2d) {
if (cmode == axis) {
if (t->con.orientation != V3D_MANIP_GLOBAL) {
if (t->con.orientation != V3D_TRANS_ORIENTATION_GLOBAL) {
stopConstraint(t);
}
else {
short orientation = (t->current_orientation != V3D_MANIP_GLOBAL ?
t->current_orientation : V3D_MANIP_LOCAL);
short orientation = (t->current_orientation != V3D_TRANS_ORIENTATION_GLOBAL ?
t->current_orientation : V3D_TRANS_ORIENTATION_LOCAL);
if (!(t->modifiers & MOD_CONSTRAINT_PLANE))
setUserConstraint(t, orientation, constraint_axis, msg2);
else if (t->modifiers & MOD_CONSTRAINT_PLANE)
@@ -947,9 +947,9 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
}
else {
if (!(t->modifiers & MOD_CONSTRAINT_PLANE))
setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_axis, msg2);
setUserConstraint(t, V3D_TRANS_ORIENTATION_GLOBAL, constraint_axis, msg2);
else if (t->modifiers & MOD_CONSTRAINT_PLANE)
setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_plane, msg3);
setUserConstraint(t, V3D_TRANS_ORIENTATION_GLOBAL, constraint_plane, msg3);
}
}
t->redraw |= TREDRAW_HARD;
@@ -1082,7 +1082,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
if (ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
/* Scale isn't normally very useful after extrude along normals, see T39756 */
if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_MANIP_NORMAL)) {
if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_TRANS_ORIENTATION_NORMAL)) {
stopConstraint(t);
}
@@ -1544,7 +1544,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
}
bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
bool ED_calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
{
TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
bool success;
@@ -1701,7 +1701,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
{
TransInfo *t = (TransInfo *)customdata;
if (t->helpline != HLP_NONE && !(t->flag & T_USES_MANIPULATOR)) {
if (t->helpline != HLP_NONE && (t->flag & T_DRAW_HELPLINES)) {
float vecrot[3], cent[2];
float mval[3] = { x, y, 0.0f };
@@ -1999,7 +1999,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
{
View3D *v3d = t->view;
v3d->twmode = t->current_orientation;
v3d->transform_orientation = t->current_orientation;
}
}
}
@@ -3422,7 +3422,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3])
constraintTransLim(t, td);
}
static void applyResize(TransInfo *t, const int mval[2])
static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td;
float mat[3][3];
@@ -3433,17 +3433,7 @@ static void applyResize(TransInfo *t, const int mval[2])
copy_v3_v3(t->values, t->auto_values);
}
else {
float ratio;
/* for manipulator, center handle, the scaling can't be done relative to center */
if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
ratio = 1.0f - ((t->mouse.imval[0] - mval[0]) + (t->mouse.imval[1] - mval[1])) / 100.0f;
}
else {
ratio = t->values[0];
}
copy_v3_fl(t->values, ratio);
copy_v3_fl(t->values, t->values[0]);
snapGridIncrement(t, t->values);
@@ -3460,8 +3450,6 @@ static void applyResize(TransInfo *t, const int mval[2])
t->con.applySize(t, NULL, mat);
}
copy_m3_m3(t->mat, mat); // used in manipulator
headerResize(t, t->values, str);
for (i = 0, td = t->data; i < t->total; i++, td++) {
@@ -5265,24 +5253,14 @@ static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3])
td->loc[1] = oldy;
}
static void applyBoneSize(TransInfo *t, const int mval[2])
static void applyBoneSize(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td = t->data;
float size[3], mat[3][3];
float ratio;
int i;
char str[UI_MAX_DRAW_STR];
// TRANSFORM_FIX_ME MOVE TO MOUSE INPUT
/* for manipulator, center handle, the scaling can't be done relative to center */
if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
ratio = 1.0f - ((t->mouse.imval[0] - mval[0]) + (t->mouse.imval[1] - mval[1])) / 100.0f;
}
else {
ratio = t->values[0];
}
copy_v3_fl(size, ratio);
copy_v3_fl(size, t->values[0]);
snapGridIncrement(t, size);
@@ -5298,8 +5276,6 @@ static void applyBoneSize(TransInfo *t, const int mval[2])
t->con.applySize(t, NULL, mat);
}
copy_m3_m3(t->mat, mat); // used in manipulator
headerBoneSize(t, size, str);
for (i = 0; i < t->total; i++, td++) {
@@ -8332,9 +8308,7 @@ static void applyTimeTranslate(TransInfo *t, const int mval[2])
}
/* handle numeric-input stuff */
t->vec[0] = t->values[0];
applyNumInput(&t->num, &t->vec[0]);
t->values[0] = t->vec[0];
applyNumInput(&t->num, t->values);
headerTimeTranslate(t, str);
applyTimeTranslateValue(t);
@@ -8499,9 +8473,9 @@ static void applyTimeSlide(TransInfo *t, const int mval[2])
/* t->values[0] = cval[0]; */ /* UNUSED (reset again later). */
/* handle numeric-input stuff */
t->vec[0] = 2.0f * (cval[0] - sval[0]) / (maxx - minx);
applyNumInput(&t->num, &t->vec[0]);
t->values[0] = (maxx - minx) * t->vec[0] / 2.0f + sval[0];
t->values[0] = 2.0f * (cval[0] - sval[0]) / (maxx - minx);
applyNumInput(&t->num, t->values);
t->values[0] = (maxx - minx) * t->values[0] / 2.0f + sval[0];
headerTimeSlide(t, sval[0], str);
applyTimeSlideValue(t, sval[0]);
@@ -8615,11 +8589,9 @@ static void applyTimeScaleValue(TransInfo *t)
static void applyTimeScale(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
/* handle numeric-input stuff */
t->vec[0] = t->values[0];
applyNumInput(&t->num, &t->vec[0]);
t->values[0] = t->vec[0];
applyNumInput(&t->num, t->values);
headerTimeScale(t, str);
applyTimeScaleValue(t);

View File

@@ -418,9 +418,6 @@ typedef struct TransInfo {
char spacetype; /* spacetype where transforming is */
char helpline; /* helpline modes (not to be confused with hotline) */
float vec[3]; /* translation, to show for widget */
float mat[3][3]; /* rot/rescale, to show for widget */
float spacemtx[3][3]; /* orientation matrix of the current space */
char spacename[64]; /* name of the current space, MAX_NAME */
@@ -498,8 +495,8 @@ typedef struct TransInfo {
#define T_CAMERA (1 << 4)
// trans on points, having no rotation/scale
#define T_POINTS (1 << 6)
// for manipulator exceptions, like scaling using center point, drawing help lines
#define T_USES_MANIPULATOR (1 << 7)
/* Draw helplines (includes constraint lines) */
#define T_DRAW_HELPLINES (1 << 7)
/* restrictions flags */
#define T_ALL_RESTRICTIONS ((1 << 8)|(1 << 9)|(1 << 10))
@@ -636,9 +633,6 @@ void flushTransMasking(TransInfo *t);
void flushTransPaintCurve(TransInfo *t);
void restoreBones(TransInfo *t);
/*********************** exported from transform_manipulator.c ********** */
bool gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */
/*********************** TransData Creation and General Handling *********** */
void createTransData(struct bContext *C, TransInfo *t);
void sort_trans_data_dist(TransInfo *t);
@@ -794,8 +788,8 @@ bool applyTransformOrientation(const struct bContext *C, float mat[3][3], char r
#define ORIENTATION_EDGE 3
#define ORIENTATION_FACE 4
int getTransformOrientation_ex(const struct bContext *C, float normal[3], float plane[3], const short around);
int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3]);
int getLocalTransformOrientation_ex(const struct bContext *C, float normal[3], float plane[3], const short around);
int getLocalTransformOrientation(const struct bContext *C, float normal[3], float plane[3]);
void freeEdgeSlideTempFaces(EdgeSlideData *sld);
void freeEdgeSlideVerts(TransInfo *t, TransCustomData *custom_data);

View File

@@ -656,7 +656,7 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte
char text[40];
switch (orientation) {
case V3D_MANIP_GLOBAL:
case V3D_TRANS_ORIENTATION_GLOBAL:
{
float mtx[3][3];
BLI_snprintf(text, sizeof(text), ftext, IFACE_("global"));
@@ -664,11 +664,11 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte
setConstraint(t, mtx, mode, text);
break;
}
case V3D_MANIP_LOCAL:
case V3D_TRANS_ORIENTATION_LOCAL:
BLI_snprintf(text, sizeof(text), ftext, IFACE_("local"));
setLocalConstraint(t, mode, text);
break;
case V3D_MANIP_NORMAL:
case V3D_TRANS_ORIENTATION_NORMAL:
BLI_snprintf(text, sizeof(text), ftext, IFACE_("normal"));
if (checkUseAxisMatrix(t)) {
setAxisMatrixConstraint(t, mode, text);
@@ -677,11 +677,11 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte
setConstraint(t, t->spacemtx, mode, text);
}
break;
case V3D_MANIP_VIEW:
case V3D_TRANS_ORIENTATION_VIEW:
BLI_snprintf(text, sizeof(text), ftext, IFACE_("view"));
setConstraint(t, t->spacemtx, mode, text);
break;
case V3D_MANIP_GIMBAL:
case V3D_TRANS_ORIENTATION_GIMBAL:
BLI_snprintf(text, sizeof(text), ftext, IFACE_("gimbal"));
setConstraint(t, t->spacemtx, mode, text);
break;
@@ -706,7 +706,7 @@ void drawConstraint(TransInfo *t)
return;
if (!(tc->mode & CON_APPLY))
return;
if (t->flag & T_USES_MANIPULATOR)
if (!(t->flag & T_DRAW_HELPLINES))
return;
if (t->flag & T_NO_CONSTRAINT)
return;

View File

@@ -1163,12 +1163,9 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->val = 0.0f;
zero_v3(t->vec);
zero_v3(t->center);
zero_v3(t->center_global);
unit_m3(t->mat);
/* if there's an event, we're modal */
if (event) {
t->flag |= T_MODAL;
@@ -1230,8 +1227,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
/* turn manipulator off during transform */
// FIXME: but don't do this when USING the manipulator...
if (t->flag & T_MODAL) {
t->twtype = v3d->twtype;
v3d->twtype = 0;
t->twtype = v3d->transform_manipulators_type;
v3d->transform_manipulators_type = 0;
}
if (v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN;
@@ -1242,7 +1239,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->around = V3D_AROUND_CURSOR;
}
t->current_orientation = v3d->twmode;
t->current_orientation = v3d->transform_orientation;
/* exceptional case */
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
@@ -1335,8 +1332,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
{
t->current_orientation = RNA_property_enum_get(op->ptr, prop);
if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C)) {
t->current_orientation = V3D_MANIP_GLOBAL;
if (t->current_orientation >= V3D_TRANS_ORIENTATION_CUSTOM + BIF_countTransformOrientation(C)) {
t->current_orientation = V3D_TRANS_ORIENTATION_GLOBAL;
}
}
@@ -1434,7 +1431,13 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
else { /* add not pet option to context when not available */
t->options |= CTX_NO_PET;
}
if (op && (prop = RNA_struct_find_property(op->ptr, "draw_helplines"))) {
if (RNA_property_boolean_get(op->ptr, prop)) {
t->flag |= T_DRAW_HELPLINES;
}
}
// Mirror is not supported with PET, turn it off.
#if 0
if (t->flag & T_PROP_EDIT) {
@@ -1516,7 +1519,7 @@ void postTrans(bContext *C, TransInfo *t)
View3D *v3d = t->sa->spacedata.first;
/* restore manipulator */
if (t->flag & T_MODAL) {
v3d->twtype = t->twtype;
v3d->transform_manipulators_type = t->twtype;
}
}
@@ -1598,8 +1601,6 @@ void restoreTransObjects(TransInfo *t)
}
}
unit_m3(t->mat);
recalcData(t);
}

File diff suppressed because it is too large Load Diff

View File

@@ -206,7 +206,7 @@ static void TRANSFORM_OT_select_orientation(struct wmOperatorType *ot)
static int delete_orientation_exec(bContext *C, wmOperator *UNUSED(op))
{
View3D *v3d = CTX_wm_view3d(C);
int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
int selected_index = (v3d->transform_orientation - V3D_TRANS_ORIENTATION_CUSTOM);
BIF_removeTransformOrientationIndex(C, selected_index);
@@ -231,7 +231,7 @@ static int delete_orientation_poll(bContext *C)
if (v3d) {
selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
selected_index = (v3d->transform_orientation - V3D_TRANS_ORIENTATION_CUSTOM);
}
return selected_index >= 0;
@@ -573,6 +573,9 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
prop = RNA_def_boolean(ot->srna, "use_accurate", 0, "Accurate", "Use accurate transformation");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
prop = RNA_def_boolean(ot->srna, "draw_helplines", 1, "Draw Helplines", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
static void TRANSFORM_OT_translate(struct wmOperatorType *ot)

View File

@@ -69,8 +69,8 @@ void BIF_clearTransformOrientation(bContext *C)
BLI_freelistN(transform_spaces);
// Need to loop over all view3d
if (v3d && v3d->twmode >= V3D_MANIP_CUSTOM) {
v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
if (v3d && v3d->transform_orientation >= V3D_TRANS_ORIENTATION_CUSTOM) {
v3d->transform_orientation = V3D_TRANS_ORIENTATION_GLOBAL; /* fallback to global */
}
}
@@ -145,7 +145,7 @@ static TransformOrientation *createBoneSpace(bContext *C, ReportList *reports,
float mat[3][3];
float normal[3], plane[3];
getTransformOrientation(C, normal, plane);
getLocalTransformOrientation(C, normal, plane);
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
BKE_reports_prepend(reports, "Cannot use zero-length bone");
@@ -165,7 +165,7 @@ static TransformOrientation *createCurveSpace(bContext *C, ReportList *reports,
float mat[3][3];
float normal[3], plane[3];
getTransformOrientation(C, normal, plane);
getLocalTransformOrientation(C, normal, plane);
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
BKE_reports_prepend(reports, "Cannot use zero-length curve");
@@ -187,7 +187,7 @@ static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports,
float normal[3], plane[3];
int type;
type = getTransformOrientation(C, normal, plane);
type = getLocalTransformOrientation(C, normal, plane);
switch (type) {
case ORIENTATION_VERT:
@@ -352,7 +352,7 @@ void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target)
if (i != -1) {
Main *bmain = CTX_data_main(C);
BKE_screen_view3d_main_twmode_remove(&bmain->screen, scene, i);
BKE_screen_view3d_main_transform_orientation_remove(&bmain->screen, scene, i);
BLI_freelinkN(transform_spaces, target);
}
}
@@ -374,7 +374,7 @@ void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target)
if (i != -1) {
View3D *v3d = CTX_wm_view3d(C);
v3d->twmode = V3D_MANIP_CUSTOM + i;
v3d->transform_orientation = V3D_TRANS_ORIENTATION_CUSTOM + i;
}
}
@@ -382,7 +382,7 @@ void BIF_selectTransformOrientationValue(bContext *C, int orientation)
{
View3D *v3d = CTX_wm_view3d(C);
if (v3d) /* currently using generic poll */
v3d->twmode = orientation;
v3d->transform_orientation = orientation;
}
int BIF_countTransformOrientation(const bContext *C)
@@ -438,32 +438,134 @@ static int count_bone_select(bArmature *arm, ListBase *lb, const bool do_it)
return total;
}
/* could move into BLI_math however this is only useful for display/editing purposes */
static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], const float angle)
{
/* X/Y are arbitrary axies, most importantly Z is the axis of rotation */
float cross_vec[3];
float quat[4];
/* this is an un-scientific method to get a vector to cross with
* XYZ intentionally YZX */
cross_vec[0] = axis[1];
cross_vec[1] = axis[2];
cross_vec[2] = axis[0];
/* X-axis */
cross_v3_v3v3(gmat[0], cross_vec, axis);
normalize_v3(gmat[0]);
axis_angle_to_quat(quat, axis, angle);
mul_qt_v3(quat, gmat[0]);
/* Y-axis */
axis_angle_to_quat(quat, axis, M_PI_2);
copy_v3_v3(gmat[1], gmat[0]);
mul_qt_v3(quat, gmat[1]);
/* Z-axis */
copy_v3_v3(gmat[2], axis);
normalize_m3(gmat);
}
static int test_rotmode_euler(short rotmode)
{
return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
}
static bool gimbal_axis(Object *ob, float gmat[3][3])
{
if (ob) {
if (ob->mode & OB_MODE_POSE) {
bPoseChannel *pchan = BKE_pose_channel_active(ob);
if (pchan) {
float mat[3][3], tmat[3][3], obmat[3][3];
if (test_rotmode_euler(pchan->rotmode)) {
eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle);
}
else { /* quat */
return 0;
}
/* apply bone transformation */
mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat);
if (pchan->parent) {
float parent_mat[3][3];
copy_m3_m4(parent_mat, pchan->parent->pose_mat);
mul_m3_m3m3(mat, parent_mat, tmat);
/* needed if object transformation isn't identity */
copy_m3_m4(obmat, ob->obmat);
mul_m3_m3m3(gmat, obmat, mat);
}
else {
/* needed if object transformation isn't identity */
copy_m3_m4(obmat, ob->obmat);
mul_m3_m3m3(gmat, obmat, tmat);
}
normalize_m3(gmat);
return 1;
}
}
else {
if (test_rotmode_euler(ob->rotmode)) {
eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode);
}
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle);
}
else { /* quat */
return 0;
}
if (ob->parent) {
float parent_mat[3][3];
copy_m3_m4(parent_mat, ob->parent->obmat);
normalize_m3(parent_mat);
mul_m3_m3m3(gmat, parent_mat, gmat);
}
return 1;
}
}
return 0;
}
void initTransformOrientation(bContext *C, TransInfo *t)
{
Object *ob = CTX_data_active_object(C);
Object *obedit = CTX_data_active_object(C);
switch (t->current_orientation) {
case V3D_MANIP_GLOBAL:
case V3D_TRANS_ORIENTATION_GLOBAL:
unit_m3(t->spacemtx);
BLI_strncpy(t->spacename, IFACE_("global"), sizeof(t->spacename));
break;
case V3D_MANIP_GIMBAL:
case V3D_TRANS_ORIENTATION_GIMBAL:
unit_m3(t->spacemtx);
if (gimbal_axis(ob, t->spacemtx)) {
BLI_strncpy(t->spacename, IFACE_("gimbal"), sizeof(t->spacename));
break;
}
/* fall-through */ /* no gimbal fallthrough to normal */
case V3D_MANIP_NORMAL:
case V3D_TRANS_ORIENTATION_NORMAL:
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
BLI_strncpy(t->spacename, IFACE_("normal"), sizeof(t->spacename));
ED_getTransformOrientationMatrix(C, t->spacemtx, t->around);
ED_getLocalTransformOrientationMatrix(C, t->spacemtx, t->around);
break;
}
/* fall-through */ /* we define 'normal' as 'local' in Object mode */
case V3D_MANIP_LOCAL:
case V3D_TRANS_ORIENTATION_LOCAL:
BLI_strncpy(t->spacename, IFACE_("local"), sizeof(t->spacename));
if (ob) {
@@ -476,7 +578,7 @@ void initTransformOrientation(bContext *C, TransInfo *t)
break;
case V3D_MANIP_VIEW:
case V3D_TRANS_ORIENTATION_VIEW:
if ((t->spacetype == SPACE_VIEW3D) &&
(t->ar->regiontype == RGN_TYPE_WINDOW))
{
@@ -493,7 +595,7 @@ void initTransformOrientation(bContext *C, TransInfo *t)
}
break;
default: /* V3D_MANIP_CUSTOM */
if (applyTransformOrientation(C, t->spacemtx, t->spacename, t->current_orientation - V3D_MANIP_CUSTOM)) {
if (applyTransformOrientation(C, t->spacemtx, t->spacename, t->current_orientation - V3D_TRANS_ORIENTATION_CUSTOM)) {
/* pass */
}
else {
@@ -584,7 +686,7 @@ static unsigned int bm_mesh_faces_select_get_n(BMesh *bm, BMVert **elems, const
}
#endif
int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3], const short around)
int getLocalTransformOrientation_ex(const bContext *C, float normal[3], float plane[3], const short around)
{
SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
@@ -1042,22 +1144,22 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
return result;
}
int getTransformOrientation(const bContext *C, float normal[3], float plane[3])
int getLocalTransformOrientation(const bContext *C, float normal[3], float plane[3])
{
/* dummy value, not V3D_AROUND_ACTIVE and not V3D_AROUND_LOCAL_ORIGINS */
short around = V3D_AROUND_CENTER_BOUNDS;
return getTransformOrientation_ex(C, normal, plane, around);
return getLocalTransformOrientation_ex(C, normal, plane, around);
}
void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], const short around)
void ED_getLocalTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], const short around)
{
float normal[3] = {0.0, 0.0, 0.0};
float plane[3] = {0.0, 0.0, 0.0};
int type;
type = getTransformOrientation_ex(C, normal, plane, around);
type = getLocalTransformOrientation_ex(C, normal, plane, around);
switch (type) {
case ORIENTATION_NORMAL:
@@ -1086,3 +1188,63 @@ void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3
unit_m3(orientation_mat);
}
}
/**
* Get (or calculate if needed) the rotation matrix for \a orientation_type.
*/
void ED_getTransformOrientationMatrix(
const bContext *C, const char orientation_type, const short around,
float r_orientation_mat[3][3])
{
Object *ob = CTX_data_active_object(C);
Object *obedit = CTX_data_active_object(C);
float mat[3][3];
BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D &&
CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW);
unit_m3(mat);
switch (orientation_type) {
case V3D_TRANS_ORIENTATION_GLOBAL:
/* use unit matrix */
break;
case V3D_TRANS_ORIENTATION_GIMBAL:
if (gimbal_axis(ob, mat)) {
break;
}
/* No break, fall-through here! If not gimbal, fall through to normal. */
case V3D_TRANS_ORIENTATION_NORMAL:
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
ED_getLocalTransformOrientationMatrix(C, mat, around);
break;
}
/* No break, fall-trough here! We define 'normal' as 'local' in Object mode. */
case V3D_TRANS_ORIENTATION_LOCAL:
if (ob && ob->mode & OB_MODE_POSE) {
/* each bone moves on its own local axis, but to avoid confusion,
* use the active pones axis for display [#33575], this works as expected on a single bone
* and users who select many bones will understand whats going on and what local means
* when they start transforming */
ED_getLocalTransformOrientationMatrix(C, mat, around);
break;
}
else if (ob) {
copy_m3_m4(mat, ob->obmat);
normalize_m3(mat);
}
break;
case V3D_TRANS_ORIENTATION_VIEW:
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
copy_m3_m4(mat, rv3d->viewinv);
normalize_m3(mat);
break;
}
default: /* custom (V3D_MANIP_CUSTOM and higher) */
applyTransformOrientation(C, mat, NULL, orientation_type - V3D_TRANS_ORIENTATION_CUSTOM);
break;
}
copy_m3_m3(r_orientation_mat, mat);
}

View File

@@ -148,6 +148,7 @@ data_to_c_simple(shaders/gpu_shader_3D_flat_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_passthrough_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl SRC)

View File

@@ -121,6 +121,7 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_3D_FLAT_COLOR,
GPU_SHADER_3D_SMOOTH_COLOR,
GPU_SHADER_3D_DEPTH_ONLY,
GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
/* basic image drawing */
GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR,

View File

@@ -74,6 +74,7 @@ extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
extern char datatoc_gpu_shader_3D_passthrough_vert_glsl[];
extern char datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl[];
extern char datatoc_gpu_shader_instance_vert_glsl[];
extern char datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl[];
@@ -724,6 +725,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
[GPU_SHADER_3D_GROUNDLINE] = { datatoc_gpu_shader_3D_passthrough_vert_glsl,
datatoc_gpu_shader_uniform_color_frag_glsl,
datatoc_gpu_shader_3D_groundline_geom_glsl },
[GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl,
datatoc_gpu_shader_uniform_color_frag_glsl },
[GPU_SHADER_2D_LINE_DASHED_COLOR] = { datatoc_gpu_shader_2D_line_dashed_vert_glsl,
datatoc_gpu_shader_2D_line_dashed_frag_glsl },

View File

@@ -0,0 +1,16 @@
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelMatrix;
uniform vec4 ClipPlane;
#if __VERSION__ == 120
attribute vec3 pos;
#else
in vec3 pos;
#endif
void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
gl_ClipDistance[0] = dot(ModelMatrix * vec4(pos, 1.0), ClipPlane);
}

View File

@@ -1636,8 +1636,6 @@ typedef struct Scene {
struct Object *obedit; /* name replaces old G.obedit */
float cursor[3]; /* 3d cursor location */
float twcent[3]; /* center for transform widget */
float twmin[3], twmax[3]; /* boundbox of selection for transform widget */
unsigned int lay; /* bitflags for layer visibility */
int layact; /* active layer */
@@ -1646,7 +1644,7 @@ typedef struct Scene {
short flag; /* various settings */
char use_nodes;
char pad[1];
char pad[5];
struct bNodeTree *nodetree;

View File

@@ -91,7 +91,6 @@ typedef struct BGpic {
/* ********************************* */
typedef struct RegionView3D {
float winmat[4][4]; /* GL_PROJECTION matrix */
float viewmat[4][4]; /* GL_MODELVIEW matrix */
float viewinv[4][4]; /* inverse of viewmat */
@@ -113,14 +112,12 @@ typedef struct RegionView3D {
struct ViewDepths *depths;
void *gpuoffscreen;
/* animated smooth view */
struct SmoothView3DStore *sms;
struct wmTimer *smooth_timer;
/* transform manipulator matrix */
float twmat[4][4];
float viewquat[4]; /* view rotation, must be kept normalized */
float dist; /* distance from 'ofs' along -viewinv[2] vector, where result is negative as is 'ofs' */
float camdx, camdy; /* camera view offsets, 1.0 = viewplane moves entire width/height */
@@ -137,8 +134,7 @@ typedef struct RegionView3D {
char pad[3];
float ofs_lock[2]; /* normalized offset for locked view: (-1, -1) bottom left, (1, 1) upper right */
short twdrawflag;
short rflag;
short rflag, pad2[3];
/* last view (use when switching out of camera view) */
@@ -146,7 +142,6 @@ typedef struct RegionView3D {
short lpersp, lview; /* lpersp can never be set to 'RV3D_CAMOB' */
float gridview;
float tw_idot[3]; /* manipulator runtime: (1 - dot) product with view vector (used to check view alignment) */
/* active rotation from NDOF or elsewhere */
@@ -210,11 +205,13 @@ typedef struct View3D {
short gridsubdiv; /* Number of subdivisions in the grid between each highlighted grid line */
char gridflag;
/* transform manipulator info */
char twtype, twmode, twflag;
/* transform manipulators info */
char transform_manipulators_type;
char transform_orientation;
char pad5;
short flag3;
/* afterdraw, for xray & transparent */
struct ListBase afterdraw_transp;
struct ListBase afterdraw_xray;
@@ -330,7 +327,10 @@ typedef struct View3D {
/* View3d->flag3 (short) */
#define V3D_SHOW_WORLD (1 << 0)
enum {
V3D_SHOW_WORLD = (1 << 0),
V3D_USE_TRANSFORM_MANIPULATORS = (1 << 1),
};
/* View3d->tmp_compat_flag */
enum {
@@ -376,24 +376,23 @@ enum {
#define V3D_SHOW_Y 4
#define V3D_SHOW_Z 8
/* View3d->twtype (bits, we can combine them) */
#define V3D_MANIP_TRANSLATE 1
#define V3D_MANIP_ROTATE 2
#define V3D_MANIP_SCALE 4
/* View3d->transform_manipulators_type (bits, we can combine them) */
enum {
V3D_MANIP_TRANSLATE = (1 << 0),
V3D_MANIP_ROTATE = (1 << 1),
V3D_MANIP_SCALE = (1 << 2),
};
/* View3d->twmode */
#define V3D_MANIP_GLOBAL 0
#define V3D_MANIP_LOCAL 1
#define V3D_MANIP_NORMAL 2
#define V3D_MANIP_VIEW 3
#define V3D_MANIP_GIMBAL 4
#define V3D_MANIP_CUSTOM 5 /* anything of value 5 or higher is custom */
/* View3d->twflag */
/* USE = user setting, DRAW = based on selection */
#define V3D_USE_MANIPULATOR 1
#define V3D_DRAW_MANIPULATOR 2
/* #define V3D_CALC_MANIPULATOR 4 */ /*UNUSED*/
/* View3d->transform_orientation */
enum {
V3D_TRANS_ORIENTATION_GLOBAL = 0,
V3D_TRANS_ORIENTATION_LOCAL = 1,
V3D_TRANS_ORIENTATION_NORMAL = 2,
V3D_TRANS_ORIENTATION_VIEW = 3,
V3D_TRANS_ORIENTATION_GIMBAL = 4,
V3D_TRANS_ORIENTATION_CUSTOM = 5,
/* anything of value 5 or higher is custom */
};
/* BGPic->flag */
/* may want to use 1 for select ? */

View File

@@ -149,13 +149,15 @@ static EnumPropertyItem draw_channels_items[] = {
};
static EnumPropertyItem transform_orientation_items[] = {
{V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", "Align the transformation axes to world space"},
{V3D_MANIP_LOCAL, "LOCAL", 0, "Local", "Align the transformation axes to the selected objects' local space"},
{V3D_MANIP_NORMAL, "NORMAL", 0, "Normal",
{V3D_TRANS_ORIENTATION_GLOBAL, "GLOBAL", 0, "Global", "Align the transformation axes to world space"},
{V3D_TRANS_ORIENTATION_LOCAL, "LOCAL", 0, "Local",
"Align the transformation axes to the selected objects' local space"},
{V3D_TRANS_ORIENTATION_NORMAL, "NORMAL", 0, "Normal",
"Align the transformation axes to average normal of selected elements "
"(bone Y axis for pose mode)"},
{V3D_MANIP_GIMBAL, "GIMBAL", 0, "Gimbal", "Align each axis to the Euler rotation axis as used for input"},
{V3D_MANIP_VIEW, "VIEW", 0, "View", "Align the transformation axes to the window"},
{V3D_TRANS_ORIENTATION_GIMBAL, "GIMBAL", 0, "Gimbal",
"Align each axis to the Euler rotation axis as used for input"},
{V3D_TRANS_ORIENTATION_VIEW, "VIEW", 0, "View", "Align the transformation axes to the window"},
// {V3D_MANIP_CUSTOM, "CUSTOM", 0, "Custom", "Use a custom transform orientation"},
{0, NULL, 0, NULL, NULL}
};
@@ -410,11 +412,13 @@ static PointerRNA rna_CurrentOrientation_get(PointerRNA *ptr)
Scene *scene = ((bScreen *)ptr->id.data)->scene;
View3D *v3d = (View3D *)ptr->data;
if (v3d->twmode < V3D_MANIP_CUSTOM)
if (v3d->transform_orientation < V3D_TRANS_ORIENTATION_CUSTOM)
return rna_pointer_inherit_refine(ptr, &RNA_TransformOrientation, NULL);
else
else {
const int ts_idx = v3d->transform_orientation - V3D_TRANS_ORIENTATION_CUSTOM;
return rna_pointer_inherit_refine(ptr, &RNA_TransformOrientation,
BLI_findlink(&scene->transform_spaces, v3d->twmode - V3D_MANIP_CUSTOM));
BLI_findlink(&scene->transform_spaces, ts_idx));
}
}
EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
@@ -424,7 +428,7 @@ EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, P
TransformOrientation *ts = NULL;
EnumPropertyItem tmp = {0, "", 0, "", ""};
EnumPropertyItem *item = NULL;
int i = V3D_MANIP_CUSTOM, totitem = 0;
int i = V3D_TRANS_ORIENTATION_CUSTOM, totitem = 0;
RNA_enum_items_add(&item, &totitem, transform_orientation_items);
@@ -2649,20 +2653,19 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_pivot_update");
prop = RNA_def_property(srna, "show_manipulator", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "twflag", V3D_USE_MANIPULATOR);
RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_USE_TRANSFORM_MANIPULATORS);
RNA_def_property_ui_text(prop, "Manipulator", "Use a 3D manipulator widget for controlling transforms");
RNA_def_property_ui_icon(prop, ICON_MANIPUL, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "transform_manipulators", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "twtype");
prop = RNA_def_property(srna, "transform_manipulators_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, manipulators_items);
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
RNA_def_property_ui_text(prop, "Transform Manipulators", "Transformation manipulators");
RNA_def_property_ui_text(prop, "Transform Manipulators", "Type of transformation the transform "
"manipulators will represent");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "transform_orientation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "twmode");
RNA_def_property_enum_items(prop, transform_orientation_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_TransformOrientation_itemf");
RNA_def_property_ui_text(prop, "Transform Orientation", "Transformation orientation");

View File

@@ -175,10 +175,10 @@ static void rna_userdef_show_manipulator_update(Main *bmain, Scene *scene, Point
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
View3D *v3d = (View3D *)sl;
if (userdef->tw_flag & V3D_USE_MANIPULATOR)
v3d->twflag |= V3D_USE_MANIPULATOR;
if (userdef->tw_flag & V3D_USE_TRANSFORM_MANIPULATORS)
v3d->flag3 |= V3D_USE_TRANSFORM_MANIPULATORS;
else
v3d->twflag &= ~V3D_USE_MANIPULATOR;
v3d->flag3 &= ~V3D_USE_TRANSFORM_MANIPULATORS;
}
}
}
@@ -3499,7 +3499,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
/* 3D transform widget */
prop = RNA_def_property(srna, "show_manipulator", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "tw_flag", V3D_USE_MANIPULATOR);
RNA_def_property_boolean_sdna(prop, NULL, "tw_flag", V3D_USE_TRANSFORM_MANIPULATORS);
RNA_def_property_ui_text(prop, "Manipulator", "Use 3D transform manipulator");
RNA_def_property_update(prop, 0, "rna_userdef_show_manipulator_update");

View File

@@ -73,6 +73,10 @@ set(SRC
manipulators/intern/wm_manipulator.c
manipulators/intern/wm_manipulatorgroup.c
manipulators/intern/wm_manipulatormap.c
manipulators/intern/manipulator_library/arrow_manipulator.c
manipulators/intern/manipulator_library/dial_manipulator.c
manipulators/intern/manipulator_library/geom_cone.c
manipulators/intern/manipulator_library/geom_cube.c
manipulators/intern/manipulator_library/manipulator_library_utils.c
WM_api.h
@@ -87,9 +91,11 @@ set(SRC
wm_subwindow.h
wm_window.h
manipulators/WM_manipulator_api.h
manipulators/WM_manipulator_library.h
manipulators/WM_manipulator_types.h
manipulators/wm_manipulator_wmapi.h
manipulators/intern/wm_manipulator_intern.h
manipulators/intern/manipulator_library/manipulator_geometry.h
manipulators/intern/manipulator_library/manipulator_library_intern.h
)

View File

@@ -44,6 +44,7 @@
/* Include external manipulator API's */
#include "manipulators/WM_manipulator_api.h"
#include "manipulators/WM_manipulator_library.h"
#ifdef __cplusplus
extern "C" {

View File

@@ -2138,7 +2138,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
/* handle user configurable manipulator-map keymap */
else if (manipulator) {
/* get user customized keymap from default one */
const wmManipulatorGroup *highlightgroup = wm_manipulator_get_parent_group(manipulator);
const wmManipulatorGroup *highlightgroup = WM_manipulator_get_parent_group(manipulator);
const wmKeyMap *keymap = WM_keymap_active(wm, highlightgroup->type->keymap);
wmKeyMapItem *kmi;

View File

@@ -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 */
@@ -67,6 +70,7 @@ void WM_manipulator_set_flag(struct wmManipulator *manipulator, const int flag,
void WM_manipulator_set_scale(struct wmManipulator *manipulator, float scale);
void WM_manipulator_set_line_width(struct wmManipulator *manipulator, const float line_width);
void WM_manipulator_set_colors(struct wmManipulator *manipulator, const float col[4], const float col_hi[4]);
struct wmManipulatorGroup *WM_manipulator_get_parent_group(const struct wmManipulator *manipulator);
/* -------------------------------------------------------------------- */

View File

@@ -0,0 +1,67 @@
/*
* ***** 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 wmManipulator;
struct wmManipulatorGroup;
/* -------------------------------------------------------------------- */
/* 3D Arrow Manipulator */
enum ArrowManipulatorStyle {
MANIPULATOR_ARROW_STYLE_CONE = 0,
MANIPULATOR_ARROW_STYLE_CUBE = 1,
};
struct wmManipulator *WM_arrow_manipulator_new(
struct wmManipulatorGroup *mgroup, const char *name, const enum ArrowManipulatorStyle style);
void WM_arrow_manipulator_set_direction(struct wmManipulator *manipulator, const float direction[3]);
void WM_arrow_manipulator_set_length(struct wmManipulator *manipulator, const float length);
/* -------------------------------------------------------------------- */
/* Dial Manipulator */
enum {
MANIPULATOR_DIAL_STYLE_RING = 0,
MANIPULATOR_DIAL_STYLE_RING_CLIPPED = 1,
MANIPULATOR_DIAL_STYLE_RING_FILLED = 2,
};
struct wmManipulator *WM_dial_manipulator_new(struct wmManipulatorGroup *mgroup, const char *name, const int style);
void WM_dial_manipulator_set_up_vector(struct wmManipulator *manipulator, const float direction[3]);
void WM_dial_manipulator_set_value(struct wmManipulator *manipulator, const double value);
#endif /* __WM_MANIPULATOR_LIBRARY_H__ */

View File

@@ -38,6 +38,7 @@
#include "BLI_compiler_attrs.h"
struct bContext;
struct wmManipulatorGroupType;
struct wmManipulatorGroup;
struct wmKeyConfig;

View File

@@ -0,0 +1,279 @@
/*
* ***** 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/arrow_manipulator.c
* \ingroup wm
*/
#include "BIF_gl.h"
#include "BKE_context.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_defs.h"
#include "DNA_listBase.h"
#include "DNA_userdef_types.h"
#include "DNA_windowmanager_types.h"
#include "GPU_immediate.h"
#include "GPU_select.h"
#include "MEM_guardedalloc.h"
#include "RNA_types.h"
#include "WM_types.h"
#include "WM_api.h"
#include "manipulator_geometry.h"
#include "manipulator_library_intern.h"
#include "WM_manipulator_types.h"
#include "wm_manipulator_wmapi.h"
#include "wm_manipulator_intern.h"
#include "WM_manipulator_library.h"
typedef struct ArrowManipulator {
wmManipulator manipulator;
int style;
float direction[3];
float length;
} ArrowManipulator;
static void arrow_draw_line(const ArrowManipulator *arrow, const float col[4], const float len)
{
VertexFormat *format = immVertexFormat();
unsigned int pos = add_attrib(format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(col);
glLineWidth(arrow->manipulator.line_width);
immBegin(GL_LINES, 2);
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
immVertex3f(pos, 0.0f, 0.0f, len);
immEnd();
immUnbindProgram();
}
static void arrow_draw_head_cone(const float col[4], const bool select)
{
const ManipulatorGeometryInfo cone_geo = {
_MANIPULATOR_nverts_cone,
_MANIPULATOR_ntris_cone,
_MANIPULATOR_verts_cone,
_MANIPULATOR_normals_cone,
_MANIPULATOR_indices_cone,
true,
};
const float scale = 0.25f;
glColor4fv(col);
glScalef(scale, scale, scale);
wm_manipulator_geometryinfo_draw(&cone_geo, select);
}
static void arrow_draw_head_cube(const float col[4], const bool select)
{
const ManipulatorGeometryInfo cone_geo = {
_MANIPULATOR_nverts_cube,
_MANIPULATOR_ntris_cube,
_MANIPULATOR_verts_cube,
_MANIPULATOR_normals_cube,
_MANIPULATOR_indices_cube,
true,
};
const float scale = 0.05f;
glColor4fv(col);
glScalef(scale, scale, scale);
glTranslatef(0.0f, 0.0f, 1.0f); /* Cube origin is at its center, needs this offset to not overlap with line. */
wm_manipulator_geometryinfo_draw(&cone_geo, select);
}
static void arrow_draw_head(const ArrowManipulator *arrow, const float col[4], const bool select)
{
switch (arrow->style) {
case MANIPULATOR_ARROW_STYLE_CONE:
arrow_draw_head_cone(col, select);
break;
case MANIPULATOR_ARROW_STYLE_CUBE:
arrow_draw_head_cube(col, select);
break;
}
}
static void arrow_draw_geom(const ArrowManipulator *arrow, const float col[4], const bool select)
{
const float len = arrow->length;
const bool use_lighting = /*select == false && ((U.manipulator_flag & V3D_SHADED_MANIPULATORS) != 0)*/ false;
glTranslatef(UNPACK3(arrow->manipulator.offset));
arrow_draw_line(arrow, col, len);
/* *** draw arrow head *** */
/* translate to line end */
glPushMatrix();
glTranslatef(0.0f, 0.0f, len);
if (use_lighting) {
glShadeModel(GL_SMOOTH);
}
arrow_draw_head(arrow, col, select);
if (use_lighting) {
glShadeModel(GL_FLAT);
}
glPopMatrix();
}
static void arrow_get_matrix(const ArrowManipulator *arrow, float r_rot[3][3], float r_mat[4][4])
{
const float up[3] = {0.0f, 0.0f, 1.0f};
rotation_between_vecs_to_mat3(r_rot, up, arrow->direction);
copy_m4_m3(r_mat, r_rot);
copy_v3_v3(r_mat[3], arrow->manipulator.origin);
mul_mat3_m4_fl(r_mat, arrow->manipulator.scale);
}
static void arrow_draw_intern(const ArrowManipulator *arrow, const bool select, const bool highlight)
{
float col[4];
float rot[3][3];
float mat[4][4];
manipulator_color_get(&arrow->manipulator, highlight, col);
arrow_get_matrix(arrow, rot, mat);
glPushMatrix();
glMultMatrixf((float *)mat);
glEnable(GL_BLEND);
arrow_draw_geom(arrow, col, select);
glDisable(GL_BLEND);
glPopMatrix();
if (arrow->manipulator.interaction_data) {
ManipulatorInteraction *inter = arrow->manipulator.interaction_data;
const float ghost_col[] = {0.5f, 0.5f, 0.5f, 0.5f};
copy_m4_m3(mat, rot);
copy_v3_v3(mat[3], inter->init_origin);
mul_mat3_m4_fl(mat, inter->init_scale);
glPushMatrix();
glMultMatrixf((float *)mat);
glEnable(GL_BLEND);
arrow_draw_geom(arrow, ghost_col, select);
glDisable(GL_BLEND);
glPopMatrix();
}
}
static void arrow_manipulator_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 arrow_manipulator_draw(const bContext *UNUSED(C), wmManipulator *manipulator)
{
arrow_draw_intern((ArrowManipulator *)manipulator, false, (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) != 0);
}
static int manipulator_arrow_invoke(bContext *UNUSED(C), const wmEvent *UNUSED(event), wmManipulator *manipulator)
{
ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__);
inter->init_scale = manipulator->scale;
// manipulator_arrow_get_final_pos(manipulator, inter->init_origin);
copy_v3_v3(inter->init_origin, manipulator->origin);
manipulator->interaction_data = inter;
return OPERATOR_RUNNING_MODAL;
}
/* -------------------------------------------------------------------- */
/** \name Arrow Manipulator API
*
* \{ */
wmManipulator *WM_arrow_manipulator_new(
wmManipulatorGroup *mgroup, const char *idname, const enum ArrowManipulatorStyle style)
{
ArrowManipulator *arrow = MEM_callocN(sizeof(*arrow), __func__);
arrow->manipulator.draw = arrow_manipulator_draw;
arrow->manipulator.render_3d_intersection = arrow_manipulator_render_3d_intersect;
arrow->manipulator.invoke = manipulator_arrow_invoke;
arrow->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE;
arrow->style = style;
arrow->length = 1.0f;
wm_manipulator_register(mgroup, &arrow->manipulator, idname);
return &arrow->manipulator;
}
/**
* Define direction the arrow will point towards
*/
void WM_arrow_manipulator_set_direction(wmManipulator *manipulator, const float direction[3])
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
copy_v3_v3(arrow->direction, direction);
normalize_v3(arrow->direction);
}
void WM_arrow_manipulator_set_length(wmManipulator *manipulator, const float length)
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
arrow->length = length;
}
/** \} */ /* Arrow Manipulator API */
/* -------------------------------------------------------------------- */
void fix_linking_manipulator_arrow(void)
{
(void)0;
}

View File

@@ -0,0 +1,337 @@
/*
* ***** 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 "ED_screen.h"
#include "ED_view3d.h"
#include "GPU_immediate.h"
#include "GPU_matrix.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_geometry.h"
#include "manipulator_library_intern.h"
typedef struct DialManipulator {
wmManipulator manipulator;
int style;
float direction[3];
/* will later be converted into angle */
double value;
} DialManipulator;
typedef struct DialInteraction {
float value_indicator_offset;
} DialInteraction;
#define DIAL_WIDTH 1.0f
#define DIAL_RESOLUTION 32
/* -------------------------------------------------------------------- */
static void dial_geom_draw(
const DialManipulator *dial, const float mat[4][4], const float clipping_plane[4], const float col[4])
{
const bool is_active = (dial->manipulator.interaction_data != NULL);
const bool use_clipping = (dial->style == MANIPULATOR_DIAL_STYLE_RING_CLIPPED) && !is_active;
const bool filled = (dial->style == MANIPULATOR_DIAL_STYLE_RING_FILLED);
const unsigned int pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 3, KEEP_FLOAT);
glLineWidth(dial->manipulator.line_width);
immBindBuiltinProgram(use_clipping ? GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR : GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(col);
if (use_clipping) {
glEnable(GL_CLIP_DISTANCE0);
immUniform4fv("ClipPlane", clipping_plane);
immUniformMatrix4fv("ModelMatrix", mat);
}
if (filled) {
imm_draw_filled_circle_3D(pos, 0.0f, 0.0f, DIAL_WIDTH, DIAL_RESOLUTION);
}
else {
imm_draw_lined_circle_3D(pos, 0.0f, 0.0f, DIAL_WIDTH, DIAL_RESOLUTION);
}
immUnbindProgram();
}
static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[3], const float col[4])
{
const unsigned int pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 3, KEEP_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(col);
gpuPushMatrix();
gpuRotateAxis(-RAD2DEGF(angle), 'Z');
immBegin(GL_LINE_STRIP, 2);
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
immVertex3fv(pos, co_outer);
immEnd();
gpuPopMatrix();
immUnbindProgram();
}
static void dial_ghostarc_draw_inner(const float init_angle_offset, const float angle, const float col[4])
{
const unsigned int pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 3, KEEP_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(col);
/* not entirely sure why the 90 degree offset is needed here and why values have to be negative */
imm_draw_filled_arc_3D(pos, -init_angle_offset + (float)M_PI_2, -angle, DIAL_WIDTH, DIAL_RESOLUTION);
immUnbindProgram();
}
static float manipulator_value_to_angle(const double value)
{
return (float)(value * M_PI * 2.0);
}
static void dial_geom_value_indicator_draw(
const DialManipulator *dial, DialInteraction *inter,
const float col_outer[4], const float col_inner[4])
{
const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; /* coordinate at which the arc drawing will be started */
const float angle = manipulator_value_to_angle(dial->value);
dial_ghostarc_draw_helpline(inter->value_indicator_offset, co_outer, col_outer);
dial_ghostarc_draw_helpline(inter->value_indicator_offset + angle, co_outer, col_outer);
dial_ghostarc_draw_inner(inter->value_indicator_offset, angle, col_inner);
}
static void dial_clipping_plane_get(DialManipulator *dial, RegionView3D *rv3d, float r_clipping_plane[4])
{
copy_v3_v3(r_clipping_plane, rv3d->viewinv[2]);
r_clipping_plane[3] = -dot_v3v3(rv3d->viewinv[2], dial->manipulator.origin);
}
static void dial_matrix_get(const DialManipulator *dial, float r_mat[4][4])
{
const float up[3] = {0.0f, 0.0f, 1.0f};
float rot[3][3];
rotation_between_vecs_to_mat3(rot, up, dial->direction);
copy_m4_m3(r_mat, rot);
copy_v3_v3(r_mat[3], dial->manipulator.origin);
mul_mat3_m4_fl(r_mat, dial->manipulator.scale);
}
static void dial_draw_intern(const bContext *C, DialManipulator *dial, const bool highlight)
{
DialInteraction *inter = dial->manipulator.interaction_data;
const bool is_active = (inter != NULL);
const bool use_value_indicator = is_active && (dial->manipulator.flag & WM_MANIPULATOR_DRAW_ACTIVE);
const bool use_clipping = (dial->style == MANIPULATOR_DIAL_STYLE_RING_CLIPPED) && !is_active;
float clipping_plane[4];
float mat[4][4];
float col[4];
BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D);
/* get all data we need */
manipulator_color_get(&dial->manipulator, highlight, col);
dial_matrix_get(dial, mat);
if (use_clipping) {
dial_clipping_plane_get(dial, CTX_wm_region_view3d(C), clipping_plane);
}
glPushMatrix();
glMultMatrixf((float *)mat);
if (use_value_indicator) {
const float col_inner[] = {0.8f, 0.8f, 0.8f, 0.4f};
/* draw rotation indicator arc first */
dial_geom_value_indicator_draw(dial, inter, col, col_inner);
}
/* draw actual dial manipulator */
dial_geom_draw(dial, mat, clipping_plane, col);
glPopMatrix();
}
static void manipulator_dial_render_3d_intersect(const bContext *C, wmManipulator *manipulator, int selectionbase)
{
DialManipulator *dial = (DialManipulator *)manipulator;
GPU_select_load_id(selectionbase);
dial_draw_intern(C, dial, false);
}
static void manipulator_dial_draw(const bContext *C, wmManipulator *manipulator)
{
DialManipulator *dial = (DialManipulator *)manipulator;
glEnable(GL_BLEND);
dial_draw_intern(C, dial, (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) != 0);
glDisable(GL_BLEND);
}
/**
* This function calculates the angle between the current mouse coordinate \a mval and the default
* starting coordinate of the value indicator arc (projected onto the 2d viewing plane). The resulting
* angle is used to offset the value indicator arc so that it starts where the user starts dragging.
*
* Not sure yet if this is only useful for rotation manipulators or for other dial manipulators
* as well. Might consider moving it to view3d_transform_manipulators.c if not.
*/
static float manipulator_init_angle_offset_get(
const DialManipulator *dial, const ARegion *ar,
const float mat[4][4], const float mval[2])
{
RegionView3D *rv3d = ar->regiondata;
/* model-space coordinate at which the arc drawing will be started (converted to world-space later) */
float co_outer[3] = {0.0f, DIAL_WIDTH, 0.0f};
float origin_2d[2], co_outer_2d[2], rel_mval[2], rel_co_outer_2d[2];
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, mat[3], view_vec);
normalize_v3_v3(axis_vec, dial->direction);
if (dot_v3v3(view_vec, axis_vec) < 0.0f) {
inv = true;
}
/* convert to world-space */
mul_m4_v3(mat, co_outer);
/* project origin and starting coordinate of arc onto 2D view plane */
ED_view3d_project_float_global(ar, mat[3], origin_2d, V3D_PROJ_TEST_NOP);
ED_view3d_project_float_global(ar, co_outer, co_outer_2d, V3D_PROJ_TEST_NOP);
/* convert to origin relative space */
sub_v2_v2v2(rel_mval, mval, origin_2d);
sub_v2_v2v2(rel_co_outer_2d, co_outer_2d, origin_2d);
/* return angle between co_outer_2d and mval around origin */
return angle_signed_v2v2(rel_co_outer_2d, rel_mval) * (inv ? -1 : 1);
}
static int manipulator_dial_invoke(bContext *C, const wmEvent *event, wmManipulator *manipulator)
{
if (manipulator->flag & WM_MANIPULATOR_DRAW_ACTIVE) {
const ARegion *ar = CTX_wm_region(C);
const DialManipulator *dial = (DialManipulator *)manipulator;
const float mval[2] = {event->mval[0], event->mval[1]};
DialInteraction *inter = MEM_callocN(sizeof(DialInteraction), __func__);
float mat[4][4];
dial_matrix_get(dial, mat);
inter->value_indicator_offset = manipulator_init_angle_offset_get(dial, ar, mat, mval);
manipulator->interaction_data = inter;
}
return OPERATOR_RUNNING_MODAL;
}
/* -------------------------------------------------------------------- */
/** \name Dial Manipulator API
*
* \{ */
wmManipulator *WM_dial_manipulator_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.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 WM_dial_manipulator_set_up_vector(wmManipulator *manipulator, const float direction[3])
{
DialManipulator *dial = (DialManipulator *)manipulator;
copy_v3_v3(dial->direction, direction);
normalize_v3(dial->direction);
}
void WM_dial_manipulator_set_value(wmManipulator *manipulator, const double value)
{
DialManipulator *dial = (DialManipulator *)manipulator;
dial->value = value;
}
/** \} */ // Dial Manipulator API
/* -------------------------------------------------------------------- */
void fix_linking_manipulator_dial(void)
{
(void)0;
}

View File

@@ -0,0 +1,71 @@
/*
* ***** 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/geom_cone.c
* \ingroup wm
*/
int _MANIPULATOR_nverts_cone = 10;
int _MANIPULATOR_ntris_cone = 16;
float _MANIPULATOR_verts_cone[][3] = {
{0.000000, 0.000000, 0.000000},
{0.000000, 0.000000, 1.000000},
{0.000000, 0.270000, 0.000000},
{0.190919, 0.190919, 0.000000},
{0.270000, -0.000000, 0.000000},
{0.190919, -0.190919, 0.000000},
{-0.000000, -0.270000, 0.000000},
{-0.190919, -0.190919, 0.000000},
{-0.270000, 0.000000, 0.000000},
{-0.190919, 0.190919, 0.000000},
};
float _MANIPULATOR_normals_cone[][3] = {
{0.000000, 0.000000, -1.000000},
{0.000000, 0.000000, 0.999969},
{0.000000, 0.848567, -0.529069},
{0.600024, 0.600024, -0.529069},
{0.848567, 0.000000, -0.529069},
{0.600024, -0.600024, -0.529069},
{0.000000, -0.848567, -0.529069},
{-0.600024, -0.600024, -0.529069},
{-0.848567, 0.000000, -0.529069},
{-0.600024, 0.600024, -0.529069},
};
unsigned short _MANIPULATOR_indices_cone[] = {
0, 2, 3,
2, 1, 3,
0, 3, 4,
3, 1, 4,
0, 4, 5,
4, 1, 5,
0, 5, 6,
5, 1, 6,
0, 6, 7,
6, 1, 7,
0, 7, 8,
7, 1, 8,
0, 8, 9,
8, 1, 9,
0, 9, 2,
9, 1, 2,
};

View File

@@ -0,0 +1,64 @@
/*
* ***** 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/geom_cube.c
* \ingroup wm
*/
int _MANIPULATOR_nverts_cube = 8;
int _MANIPULATOR_ntris_cube = 12;
float _MANIPULATOR_verts_cube[][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},
};
float _MANIPULATOR_normals_cube[][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},
};
unsigned short _MANIPULATOR_indices_cube[] = {
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,
};

View File

@@ -0,0 +1,60 @@
/*
* ***** 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/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.c
*/
#ifndef __MANIPULATOR_GEOMETRY_H__
#define __MANIPULATOR_GEOMETRY_H__
/* cone */
extern int _MANIPULATOR_nverts_cone;
extern int _MANIPULATOR_ntris_cone;
extern float _MANIPULATOR_verts_cone[][3];
extern float _MANIPULATOR_normals_cone[][3];
extern unsigned short _MANIPULATOR_indices_cone[];
/* cube */
extern int _MANIPULATOR_nverts_cube;
extern int _MANIPULATOR_ntris_cube;
extern float _MANIPULATOR_verts_cube[][3];
extern float _MANIPULATOR_normals_cube[][3];
extern unsigned short _MANIPULATOR_indices_cube[];
#endif /* __MANIPULATOR_GEOMETRY_H__ */

View File

@@ -31,6 +31,25 @@
#ifndef __MANIPULATOR_LIBRARY_INTERN_H__
#define __MANIPULATOR_LIBRARY_INTERN_H__
struct wmManipulator;
/* -------------------------------------------------------------------- */
/* 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 ManipulatorGeometryInfo *info, const bool select);
/* -------------------------------------------------------------------- */
/* Manipulator handling */
/* distance around which manipulators respond to input (and get highlighted) */
#define MANIPULATOR_HOTSPOT 14.0f
@@ -77,23 +96,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__ */

View File

@@ -31,6 +31,8 @@
* \brief This file contains functions for common behaviors of manipulators.
*/
#include "BIF_gl.h"
#include "BKE_context.h"
#include "BLI_math.h"
@@ -48,6 +50,49 @@
/* factor for precision tweaking */
#define MANIPULATOR_PRECISION_FAC 0.05f
/* -------------------------------------------------------------------- */
/* Manipulator drawing */
/**
* Main draw call for ManipulatorGeometryInfo data.
*/
void wm_manipulator_geometryinfo_draw(const ManipulatorGeometryInfo *info, const bool UNUSED(select))
{
GLuint buf[2];
glGenBuffers(2, buf);
/* vertex buffer */
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, buf[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * info->nverts, info->verts, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
/* normal buffer */
/* TODO normal buffer for lighting (if we need this?) */
/* index buffer */
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);
glDisableVertexAttribArray(0);
glDeleteBuffers(2, buf);
}
/* -------------------------------------------------------------------- */
/* Manipulator handling */
BLI_INLINE float manipulator_offset_from_value_constr(
const float range_fac, const float min, const float range, const float value,

View File

@@ -66,10 +66,10 @@ wmManipulator *WM_manipulator_new(
manipulator->render_3d_intersection = render_3d_intersection;
/* XXX */
// fix_linking_manipulator_arrow();
fix_linking_manipulator_arrow();
// fix_linking_manipulator_arrow2d();
// fix_linking_manipulator_cage();
// fix_linking_manipulator_dial();
fix_linking_manipulator_dial();
// fix_linking_manipulator_facemap();
// fix_linking_manipulator_primitive();
@@ -157,7 +157,7 @@ void WM_manipulator_delete(ListBase *manipulatorlist, wmManipulatorMap *mmap, wm
MEM_freeN(manipulator);
}
wmManipulatorGroup *wm_manipulator_get_parent_group(const wmManipulator *manipulator)
wmManipulatorGroup *WM_manipulator_get_parent_group(const wmManipulator *manipulator)
{
return manipulator->mgroup;
}
@@ -207,6 +207,13 @@ PointerRNA *WM_manipulator_set_operator(wmManipulator *manipulator, const char *
return NULL;
}
void WM_manipulator_set_custom_handler(
wmManipulator *manipulator,
int (*handler)(bContext *, const wmEvent *, wmManipulator *, const int))
{
manipulator->handler = handler;
}
/**
* \brief Set manipulator select callback.
*

View File

@@ -128,10 +128,10 @@ enum {
void wm_manipulator_register(struct wmManipulatorGroup *mgroup, struct wmManipulator *manipulator, const char *name);
bool wm_manipulator_deselect(struct wmManipulatorMap *mmap, struct wmManipulator *manipulator);
bool wm_manipulator_select(bContext *C, struct wmManipulatorMap *mmap, struct wmManipulator *manipulator);
bool wm_manipulator_select(struct bContext *C, struct wmManipulatorMap *mmap, struct wmManipulator *manipulator);
void wm_manipulator_calculate_scale(struct wmManipulator *manipulator, const bContext *C);
void wm_manipulator_update(struct wmManipulator *manipulator, const bContext *C, const bool refresh_map);
void wm_manipulator_calculate_scale(struct wmManipulator *manipulator, const struct bContext *C);
void wm_manipulator_update(struct wmManipulator *manipulator, const struct bContext *C, const bool refresh_map);
bool wm_manipulator_is_visible(struct wmManipulator *manipulator);
void fix_linking_manipulator_arrow(void);
@@ -153,7 +153,7 @@ 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_free(struct bContext *C, struct wmManipulatorMap *mmap, struct wmManipulatorGroup *mgroup);
void wm_manipulatorgroup_manipulator_register(struct wmManipulatorGroup *mgroup, wmManipulator *manipulator);
wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator(
const struct wmManipulatorGroup *mgroup, struct bContext *C, const struct wmEvent *event,
@@ -213,18 +213,5 @@ struct wmManipulatorMapType {
void wm_manipulatormap_selected_delete(wmManipulatorMap *mmap);
bool wm_manipulatormap_deselect_all(struct wmManipulatorMap *mmap, wmManipulator ***sel);
/* -------------------------------------------------------------------- */
/* Manipulator drawing */
typedef struct ManipulatorGeometryInfo {
int nverts;
int ntris;
float (*verts)[3];
float (*normals)[3];
unsigned short *indices;
bool init;
} ManipulatorGeometryInfo;
#endif /* __WM_MANIPULATOR_INTERN_H__ */

View File

@@ -628,7 +628,7 @@ void wm_manipulatormap_set_active_manipulator(
if (ot) {
/* first activate the manipulator itself */
if (manipulator->invoke && manipulator->handler) {
if (manipulator->invoke) {
manipulator->invoke(C, event, manipulator);
}
@@ -652,7 +652,7 @@ void wm_manipulatormap_set_active_manipulator(
}
}
else {
if (manipulator->invoke && manipulator->handler) {
if (manipulator->invoke) {
manipulator->invoke(C, event, manipulator);
}
}

View File

@@ -38,6 +38,7 @@
#ifndef __WM_MANIPULATOR_WMAPI_H__
#define __WM_MANIPULATOR_WMAPI_H__
struct wmEvent;
struct wmEventHandler;
struct wmManipulatorMap;
struct wmOperatorType;
@@ -49,8 +50,6 @@ struct wmOperator;
typedef void (*wmManipulatorSelectFunc)(struct bContext *, struct wmManipulator *, const int);
struct wmManipulatorGroup *wm_manipulator_get_parent_group(const struct wmManipulator *manipulator);
/* -------------------------------------------------------------------- */
/* wmManipulatorGroup */
@@ -70,19 +69,19 @@ void wm_manipulatormaptypes_free(void);
void wm_manipulators_keymap(struct wmKeyConfig *keyconf);
void wm_manipulatormaps_handled_modal_update(
bContext *C, struct wmEvent *event, struct wmEventHandler *handler,
struct bContext *C, struct wmEvent *event, struct wmEventHandler *handler,
const struct wmOperatorType *ot);
void wm_manipulatormap_handler_context(bContext *C, struct wmEventHandler *handler);
void wm_manipulatormap_handler_context(struct bContext *C, struct wmEventHandler *handler);
struct wmManipulator *wm_manipulatormap_find_highlighted_manipulator(
struct wmManipulatorMap *mmap, bContext *C,
struct wmManipulatorMap *mmap, struct bContext *C,
const struct wmEvent *event, unsigned char *part);
void wm_manipulatormap_set_highlighted_manipulator(
struct wmManipulatorMap *mmap, const bContext *C,
struct wmManipulatorMap *mmap, const struct bContext *C,
struct wmManipulator *manipulator, unsigned char part);
struct wmManipulator *wm_manipulatormap_get_highlighted_manipulator(struct wmManipulatorMap *mmap);
void wm_manipulatormap_set_active_manipulator(
struct wmManipulatorMap *mmap, bContext *C,
struct wmManipulatorMap *mmap, struct bContext *C,
const struct wmEvent *event, struct wmManipulator *manipulator);
struct wmManipulator *wm_manipulatormap_get_active_manipulator(struct wmManipulatorMap *mmap);

View File

@@ -736,6 +736,7 @@ int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title,
/* RNA COLLADA dependency */
int collada_export(struct Scene *sce,
struct SceneLayer *scene_layer,
const char *filepath,
int apply_modifiers,
BC_export_mesh_type export_mesh_type,