diff options
author | Matt Ebb <matt@mke3.net> | 2011-11-04 06:31:00 +0400 |
---|---|---|
committer | Matt Ebb <matt@mke3.net> | 2011-11-04 06:31:00 +0400 |
commit | 7e9bc22925f3669248bf211f4f3049471cf23b2b (patch) | |
tree | e4d7b527ec10d2c8f1762258cd73bb4973f58f0d /source | |
parent | 2d787e6e015e54e760086266415d66cad5d1edec (diff) |
Enabled ndof devices for controlling colour wheel and cube UI controls
(eg. colour pickers). Tilting the ndof device up and down and rolling it left and
right will move the 'colour cursor' in screen x and y, and twisting the ndof device
will rotate the cursor around the colour wheel (hue). Now you can turn off the
lights and pretend you have a fancy DI deck!
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 130 |
1 files changed, 129 insertions, 1 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index e49cb4898d9..0f230df049e 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3216,6 +3216,63 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, return changed; } +static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOFMotionData *ndof, int shift) +{ + float *hsv= ui_block_hsv_get(but->block); + float rgb[3]; + float sensitivity = (shift?0.15:0.3) * ndof->dt; + + int color_profile = but->block->color_profile; + + if (but->rnaprop) { + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) + color_profile = BLI_PR_NONE; + } + + ui_get_but_vectorf(but, rgb); + rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); + + switch((int)but->a1) { + case UI_GRAD_SV: + hsv[2] += ndof->ry * sensitivity; + hsv[1] += ndof->rx * sensitivity; + break; + case UI_GRAD_HV: + hsv[0] += ndof->ry * sensitivity; + hsv[2] += ndof->rx * sensitivity; + break; + case UI_GRAD_HS: + hsv[0] += ndof->ry * sensitivity; + hsv[1] += ndof->rx * sensitivity; + break; + case UI_GRAD_H: + hsv[0] += ndof->ry * sensitivity; + break; + case UI_GRAD_S: + hsv[1] += ndof->ry * sensitivity; + break; + case UI_GRAD_V: + hsv[2] += ndof->ry * sensitivity; + break; + case UI_GRAD_V_ALT: + /* vertical 'value' strip */ + + /* exception only for value strip - use the range set in but->min/max */ + hsv[2] += ndof->rx * sensitivity; + + if (color_profile) + hsv[2] = srgb_to_linearrgb(hsv[2]); + + CLAMP(hsv[2], but->softmin, but->softmax); + default: + assert(!"invalid hsv type"); + } + + hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); + copy_v3_v3(data->vec, rgb); + ui_set_but_vectorf(but, data->vec); +} + static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) { int mx, my; @@ -3238,6 +3295,16 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu return WM_UI_HANDLER_BREAK; } + else if (event->type == NDOF_MOTION) { + wmNDOFMotionData *ndof = (wmNDOFMotionData*) event->customdata; + + ui_ndofedit_but_HSVCUBE(but, data, ndof, event->shift); + + button_activate_state(C, but, BUTTON_STATE_EXIT); + ui_apply_button(C, but->block, but, data, 1); + + return WM_UI_HANDLER_BREAK; + } /* XXX hardcoded keymap check.... */ else if (ELEM(event->type, ZEROKEY, PAD0) && event->val == KM_PRESS) { if (but->a1==UI_GRAD_V_ALT){ @@ -3337,11 +3404,62 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx return changed; } +static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, wmNDOFMotionData *ndof, int shift) +{ + float *hsv= ui_block_hsv_get(but->block); + float rgb[3]; + float phi, r, sqr, v[2]; + float sensitivity = (shift?0.15:0.3) * ndof->dt; + + ui_get_but_vectorf(but, rgb); + rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); + + /* Convert current colour on hue/sat disc to circular coordinates phi, r */ + phi = fmodf(hsv[0]+0.25, 1.0f) * -2.0f*M_PI; + r = hsv[1]; + sqr = r>0.f?sqrtf(r):1; + + /* Convert to 2d vectors */ + v[0] = r * cos(phi); + v[1] = r * sin(phi); + + /* Use ndof device y and x rotation to move the vector in 2d space */ + v[0] += ndof->ry * sensitivity; + v[1] += ndof->rx * sensitivity; + + /* convert back to polar coords on circle */ + phi = atan2(v[0], v[1])/(2.0f*(float)M_PI) + 0.5f; + + /* use ndof z rotation to additionally rotate hue */ + phi -= ndof->rz * sensitivity * 0.5; + + r = len_v2(v); + CLAMP(r, 0.0f, 1.0f); + + /* convert back to hsv values, in range [0,1] */ + hsv[0] = fmodf(phi, 1.0); + hsv[1] = r; + + /* exception, when using color wheel in 'locked' value state: + * allow choosing a hue for black values, by giving a tiny increment */ + if (but->flag & UI_BUT_COLOR_LOCK) { // lock + if (hsv[2] == 0.f) hsv[2] = 0.0001f; + } + + hsv_to_rgb(hsv[0], hsv[1], hsv[2], data->vec, data->vec+1, data->vec+2); + + if((but->flag & UI_BUT_VEC_SIZE_LOCK) && (data->vec[0] || data->vec[1] || data->vec[2])) { + normalize_v3(data->vec); + mul_v3_fl(data->vec, but->a2); + } + + ui_set_but_vectorf(but, data->vec); +} + static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) { int mx, my; - mx= event->x; my= event->y; ui_window_to_block(data->region, block, &mx, &my); @@ -3360,6 +3478,16 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle return WM_UI_HANDLER_BREAK; } + else if (event->type == NDOF_MOTION) { + wmNDOFMotionData *ndof = (wmNDOFMotionData*) event->customdata; + + ui_ndofedit_but_HSVCIRCLE(but, data, ndof, event->shift); + + button_activate_state(C, but, BUTTON_STATE_EXIT); + ui_apply_button(C, but->block, but, data, 1); + + return WM_UI_HANDLER_BREAK; + } /* XXX hardcoded keymap check.... */ else if (ELEM(event->type, ZEROKEY, PAD0) && event->val == KM_PRESS) { int len; |