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!
This commit is contained in:
Matt Ebb 2011-11-04 02:31:00 +00:00
parent 2d787e6e01
commit 7e9bc22925

@ -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;