More radial control work.
* Added a rotation setting to brush (and brush RNA) * Brought back strength and rotation modes for radial control * Brought back brush texture for radial control * Turned off display of sculpt brush during radial control operator
This commit is contained in:
@@ -609,32 +609,6 @@ static void flip_coord(float out[3], float in[3], const char symm)
|
||||
out[2]= in[2];
|
||||
}
|
||||
|
||||
/* Use the warpfac field in MTex to store a rotation value for sculpt textures. Value is in degrees */
|
||||
static float sculpt_tex_angle(Sculpt *sd)
|
||||
{
|
||||
Brush *br = sd->brush;
|
||||
if(br->texact!=-1 && br->mtex[br->texact])
|
||||
return br->mtex[br->texact]->warpfac;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_tex_angle(Sculpt *sd, const float f)
|
||||
{
|
||||
Brush *br = sd->brush;
|
||||
if(br->texact != -1 && br->mtex[br->texact])
|
||||
br->mtex[br->texact]->warpfac = f;
|
||||
}
|
||||
|
||||
static float to_rad(const float deg)
|
||||
{
|
||||
return deg * (M_PI/180.0f);
|
||||
}
|
||||
|
||||
static float to_deg(const float rad)
|
||||
{
|
||||
return rad * (180.0f/M_PI);
|
||||
}
|
||||
|
||||
/* Get a pixel from the texcache at (px, py) */
|
||||
static unsigned char get_texcache_pixel(const SculptSession *ss, int px, int py)
|
||||
{
|
||||
@@ -701,7 +675,7 @@ static float tex_strength(Sculpt *sd, float *point, const float len)
|
||||
}
|
||||
else if(ss->texcache) {
|
||||
const float bsize= ss->cache->pixel_radius * 2;
|
||||
const float rot= to_rad(sculpt_tex_angle(sd)) + ss->cache->rotation;
|
||||
const float rot= sd->brush->rot + ss->cache->rotation;
|
||||
int px, py;
|
||||
float flip[3], point_2d[2];
|
||||
|
||||
@@ -1016,7 +990,7 @@ static void projverts_clear_inside(SculptSession *ss)
|
||||
ss->projverts[i].inside = 0;
|
||||
}
|
||||
|
||||
static void sculpt_update_tex(Sculpt *sd)
|
||||
static void sculpt_update_tex(Sculpt *sd, int half_size)
|
||||
{
|
||||
SculptSession *ss= sd->session;
|
||||
Brush *br = sd->brush;
|
||||
@@ -1035,7 +1009,7 @@ static void sculpt_update_tex(Sculpt *sd)
|
||||
}
|
||||
|
||||
/* Need to allocate a bigger buffer for bigger brush size */
|
||||
ss->texcache_side = sd->brush->size * 2;
|
||||
ss->texcache_side = half_size * 2;
|
||||
if(!ss->texcache || ss->texcache_side > ss->texcache_actual) {
|
||||
ss->texcache = MEM_callocN(sizeof(int) * ss->texcache_side * ss->texcache_side, "Sculpt Texture cache");
|
||||
ss->texcache_actual = ss->texcache_side;
|
||||
@@ -1074,99 +1048,6 @@ static void sculpt_update_tex(Sculpt *sd)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: Used anywhere?
|
||||
void sculptmode_set_strength(const int delta)
|
||||
{
|
||||
int val = sculptmode_brush()->strength + delta;
|
||||
if(val < 1) val = 1;
|
||||
if(val > 100) val = 100;
|
||||
sculptmode_brush()->strength= val;
|
||||
}*/
|
||||
|
||||
/* XXX: haven't brought in the radial control files, not sure where to put them. Note that all the paint modes should have access to radial control! */
|
||||
#if 0
|
||||
static void sculpt_radialcontrol_callback(const int mode, const int val)
|
||||
{
|
||||
SculptSession *ss = sculpt_session();
|
||||
BrushData *br = sculptmode_brush();
|
||||
|
||||
if(mode == RADIALCONTROL_SIZE)
|
||||
br->size = val;
|
||||
else if(mode == RADIALCONTROL_STRENGTH)
|
||||
br->strength = val;
|
||||
else if(mode == RADIALCONTROL_ROTATION)
|
||||
set_tex_angle(val);
|
||||
|
||||
ss->radialcontrol = NULL;
|
||||
}
|
||||
|
||||
/* Returns GL handle to brush texture */
|
||||
static GLuint sculpt_radialcontrol_calctex()
|
||||
{
|
||||
Sculpt *sd= sculpt_data();
|
||||
SculptSession *ss= sculpt_session();
|
||||
int i, j;
|
||||
const int tsz = ss->texcache_side;
|
||||
float *texdata= MEM_mallocN(sizeof(float)*tsz*tsz, "Brush preview");
|
||||
GLuint tex;
|
||||
|
||||
if(sd->tex_mode!=SCULPTREPT_3D)
|
||||
sculptmode_update_tex();
|
||||
for(i=0; i<tsz; ++i)
|
||||
for(j=0; j<tsz; ++j) {
|
||||
float magn= sqrt(pow(i-tsz/2,2)+pow(j-tsz/2,2));
|
||||
if(sd->texfade)
|
||||
texdata[i*tsz+j]= curve_strength(magn,tsz/2);
|
||||
else
|
||||
texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0;
|
||||
}
|
||||
if(sd->texact != -1 && ss->texcache) {
|
||||
for(i=0; i<tsz; ++i)
|
||||
for(j=0; j<tsz; ++j) {
|
||||
const int col= ss->texcache[i*tsz+j];
|
||||
texdata[i*tsz+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
|
||||
}
|
||||
}
|
||||
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tsz, tsz, 0, GL_ALPHA, GL_FLOAT, texdata);
|
||||
MEM_freeN(texdata);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
void sculpt_radialcontrol_start(int mode)
|
||||
{
|
||||
Sculpt *sd = sculpt_data();
|
||||
SculptSession *ss = sculpt_session();
|
||||
BrushData *br = sculptmode_brush();
|
||||
int orig=1, max=100;
|
||||
|
||||
if(mode == RADIALCONTROL_SIZE) {
|
||||
orig = br->size;
|
||||
max = 200;
|
||||
}
|
||||
else if(mode == RADIALCONTROL_STRENGTH) {
|
||||
orig = br->strength;
|
||||
max = 100;
|
||||
}
|
||||
else if(mode == RADIALCONTROL_ROTATION) {
|
||||
if(sd->texact!=-1 && sd->mtex[sd->texact]) {
|
||||
orig = sculpt_tex_angle();
|
||||
max = 360;
|
||||
}
|
||||
else
|
||||
mode = RADIALCONTROL_NONE;
|
||||
}
|
||||
|
||||
if(mode != RADIALCONTROL_NONE) {
|
||||
ss->radialcontrol= radialcontrol_start(mode, sculpt_radialcontrol_callback, orig, max,
|
||||
sculpt_radialcontrol_calctex());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void sculptmode_selectbrush_menu(void)
|
||||
{
|
||||
/* XXX: I guess menus belong elsewhere too?
|
||||
@@ -1344,6 +1225,43 @@ void sculptmode_draw_mesh(int only_damaged)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sculpt_poll(bContext *C)
|
||||
{
|
||||
return G.f & G_SCULPTMODE && CTX_wm_area(C)->spacetype == SPACE_VIEW3D &&
|
||||
CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW;
|
||||
}
|
||||
|
||||
/*** Sculpt Cursor ***/
|
||||
static void draw_paint_cursor(bContext *C, int x, int y, void *customdata)
|
||||
{
|
||||
Sculpt *sd= CTX_data_tool_settings(C)->sculpt;
|
||||
|
||||
glTranslatef((float)x, (float)y, 0.0f);
|
||||
|
||||
glColor4ub(255, 100, 100, 128);
|
||||
glEnable( GL_LINE_SMOOTH );
|
||||
glEnable(GL_BLEND);
|
||||
glutil_draw_lined_arc(0.0, M_PI*2.0, sd->brush->size, 40);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable( GL_LINE_SMOOTH );
|
||||
|
||||
glTranslatef((float)-x, (float)-y, 0.0f);
|
||||
}
|
||||
|
||||
static void toggle_paint_cursor(bContext *C)
|
||||
{
|
||||
Sculpt *s = CTX_data_scene(C)->toolsettings->sculpt;
|
||||
|
||||
if(s->session->cursor) {
|
||||
WM_paint_cursor_end(CTX_wm_manager(C), s->session->cursor);
|
||||
s->session->cursor = NULL;
|
||||
}
|
||||
else {
|
||||
s->session->cursor =
|
||||
WM_paint_cursor_activate(CTX_wm_manager(C), sculpt_poll, draw_paint_cursor, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void sculpt_undo_push(bContext *C, Sculpt *sd)
|
||||
{
|
||||
switch(sd->brush->sculpt_tool) {
|
||||
@@ -1366,10 +1284,37 @@ static void sculpt_undo_push(bContext *C, Sculpt *sd)
|
||||
}
|
||||
}
|
||||
|
||||
static int sculpt_poll(bContext *C)
|
||||
static ImBuf *sculpt_radial_control_texture(bContext *C)
|
||||
{
|
||||
return G.f & G_SCULPTMODE && CTX_wm_area(C)->spacetype == SPACE_VIEW3D &&
|
||||
CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW;
|
||||
Sculpt *s = CTX_data_scene(C)->toolsettings->sculpt;
|
||||
ImBuf *im = MEM_callocN(sizeof(ImBuf), "radial control texture");
|
||||
unsigned int *texcache;
|
||||
int side = 256;
|
||||
int half = side / 2;
|
||||
int i, j;
|
||||
|
||||
sculpt_update_tex(s, half);
|
||||
texcache = s->session->texcache;
|
||||
im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect");
|
||||
im->x = im->y = side;
|
||||
|
||||
for(i=0; i<side; ++i) {
|
||||
for(j=0; j<side; ++j) {
|
||||
float magn= sqrt(pow(i - half, 2) + pow(j - half, 2));
|
||||
im->rect_float[i*side + j]= curve_strength(s->brush->curve, magn, half);
|
||||
}
|
||||
}
|
||||
|
||||
/* Modulate curve with texture */
|
||||
if(texcache) {
|
||||
for(i=0; i<side; ++i)
|
||||
for(j=0; j<side; ++j) {
|
||||
const int col= texcache[i*side+j];
|
||||
im->rect_float[i*side+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
static int sculpt_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
@@ -1382,25 +1327,38 @@ static int sculpt_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *ev
|
||||
original_value = br->size;
|
||||
else if(mode == WM_RADIALCONTROL_STRENGTH)
|
||||
original_value = br->alpha;
|
||||
/*else if(mode == WM_RADIALCONTROL_ANGLE)
|
||||
original_value = br->rotation;*/
|
||||
else if(mode == WM_RADIALCONTROL_ANGLE)
|
||||
original_value = br->rot;
|
||||
|
||||
toggle_paint_cursor(C);
|
||||
|
||||
RNA_float_set(op->ptr, "initial_value", original_value);
|
||||
op->customdata = sculpt_radial_control_texture(C);
|
||||
|
||||
return WM_radial_control_invoke(C, op, event);
|
||||
}
|
||||
|
||||
static int sculpt_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
int ret = WM_radial_control_modal(C, op, event);
|
||||
if(ret != OPERATOR_RUNNING_MODAL)
|
||||
toggle_paint_cursor(C);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sculpt_radial_control_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Brush *br = CTX_data_scene(C)->toolsettings->sculpt->brush;
|
||||
int mode = RNA_int_get(op->ptr, "mode");
|
||||
float new_value = RNA_float_get(op->ptr, "new_value");
|
||||
const float conv = 0.017453293;
|
||||
|
||||
if(mode == WM_RADIALCONTROL_SIZE)
|
||||
br->size = new_value;
|
||||
else if(mode == WM_RADIALCONTROL_STRENGTH)
|
||||
br->alpha = new_value;
|
||||
/*else if(mode == WM_RADIALCONTROL_ANGLE)
|
||||
br->rotation = new_value;*/
|
||||
else if(mode == WM_RADIALCONTROL_ANGLE)
|
||||
br->rot = new_value * conv;
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1414,6 +1372,7 @@ static void SCULPT_OT_radial_control(wmOperatorType *ot)
|
||||
ot->idname= "SCULPT_OT_radial_control";
|
||||
|
||||
ot->invoke= sculpt_radial_control_invoke;
|
||||
ot->modal= sculpt_radial_control_modal;
|
||||
ot->exec= sculpt_radial_control_exec;
|
||||
ot->poll= sculpt_poll;
|
||||
}
|
||||
@@ -1618,7 +1577,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
|
||||
/* TODO: Shouldn't really have to do this at the start of every
|
||||
stroke, but sculpt would need some sort of notification when
|
||||
changes are made to the texture. */
|
||||
sculpt_update_tex(sd);
|
||||
sculpt_update_tex(sd, sd->brush->size);
|
||||
|
||||
/* add modal handler */
|
||||
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
|
||||
@@ -1699,7 +1658,7 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
|
||||
view3d_operator_needs_opengl(C);
|
||||
sculpt_update_cache_invariants(sd, C, op);
|
||||
sculptmode_update_all_projverts(sd->session);
|
||||
sculpt_update_tex(sd);
|
||||
sculpt_update_tex(sd, sd->brush->size);
|
||||
|
||||
RNA_BEGIN(op->ptr, itemptr, "stroke") {
|
||||
sculpt_update_cache_variants(sd, &itemptr);
|
||||
@@ -1759,23 +1718,6 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
|
||||
|
||||
/**** Toggle operator for turning sculpt mode on or off ****/
|
||||
|
||||
/* XXX: The code for drawing all the paint cursors is really the same, would be better to unify them */
|
||||
static void draw_paint_cursor(bContext *C, int x, int y, void *customdata)
|
||||
{
|
||||
Sculpt *sd= CTX_data_tool_settings(C)->sculpt;
|
||||
|
||||
glTranslatef((float)x, (float)y, 0.0f);
|
||||
|
||||
glColor4ub(255, 100, 100, 128);
|
||||
glEnable( GL_LINE_SMOOTH );
|
||||
glEnable(GL_BLEND);
|
||||
glutil_draw_lined_arc(0.0, M_PI*2.0, sd->brush->size, 40);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable( GL_LINE_SMOOTH );
|
||||
|
||||
glTranslatef((float)-x, (float)-y, 0.0f);
|
||||
}
|
||||
|
||||
static int sculpt_toggle_mode(bContext *C, wmOperator *op)
|
||||
{
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
@@ -1784,7 +1726,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op)
|
||||
/* Leave sculptmode */
|
||||
G.f &= ~G_SCULPTMODE;
|
||||
|
||||
WM_paint_cursor_end(CTX_wm_manager(C), ts->sculpt->session->cursor);
|
||||
toggle_paint_cursor(C);
|
||||
|
||||
sculptsession_free(ts->sculpt);
|
||||
|
||||
@@ -1806,9 +1748,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op)
|
||||
MEM_freeN(ts->sculpt->session);
|
||||
ts->sculpt->session = MEM_callocN(sizeof(SculptSession), "sculpt session");
|
||||
|
||||
/* Activate visible brush */
|
||||
ts->sculpt->session->cursor =
|
||||
WM_paint_cursor_activate(CTX_wm_manager(C), sculpt_poll, draw_paint_cursor, NULL);
|
||||
toggle_paint_cursor(C);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -99,9 +99,9 @@ void view3d_keymap(wmWindowManager *wm)
|
||||
|
||||
WM_keymap_verify_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
RNA_enum_set(WM_keymap_verify_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
|
||||
//RNA_enum_set(WM_keymap_verify_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
|
||||
//RNA_enum_set(WM_keymap_verify_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE);
|
||||
|
||||
WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
|
||||
@@ -63,9 +63,13 @@ typedef struct Brush {
|
||||
float rgb[3]; /* color */
|
||||
float alpha; /* opacity */
|
||||
|
||||
float rot; /* rotation in radians */
|
||||
|
||||
short texact; /* active texture */
|
||||
char sculpt_tool; /* active tool */
|
||||
char tex_mode;
|
||||
|
||||
char pad[4];
|
||||
} Brush;
|
||||
|
||||
/* Brush.flag */
|
||||
|
||||
@@ -46,6 +46,20 @@ static void *rna_Brush_active_texture_get(PointerRNA *ptr)
|
||||
return brush->mtex[(int)brush->texact];
|
||||
}
|
||||
|
||||
static float rna_Brush_rotation_get(PointerRNA *ptr)
|
||||
{
|
||||
Brush *brush= (Brush*)ptr->data;
|
||||
const float conv = 57.295779506;
|
||||
return brush->rot * conv;
|
||||
}
|
||||
|
||||
static void rna_Brush_rotation_set(PointerRNA *ptr, float v)
|
||||
{
|
||||
Brush *brush= (Brush*)ptr->data;
|
||||
const float conv = 0.017453293;
|
||||
brush->rot = v * conv;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void rna_def_brush(BlenderRNA *brna)
|
||||
@@ -122,6 +136,12 @@ void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_float_sdna(prop, NULL, "alpha");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Strength", "The amount of pressure on the brush.");
|
||||
|
||||
prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "rot");
|
||||
RNA_def_property_range(prop, 0, 360);
|
||||
RNA_def_property_float_funcs(prop, "rna_Brush_rotation_get", "rna_Brush_rotation_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Rotation", "Angle of the brush texture.");
|
||||
|
||||
/* flag */
|
||||
prop= RNA_def_property(srna, "airbrush", PROP_BOOLEAN, PROP_NONE);
|
||||
|
||||
@@ -158,6 +158,7 @@ void WM_gesture_end(struct bContext *C, struct wmGesture *gesture);
|
||||
|
||||
/* radial control operator */
|
||||
int WM_radial_control_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
|
||||
int WM_radial_control_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
|
||||
void WM_OT_radial_control_partial(struct wmOperatorType *ot);
|
||||
|
||||
/* OpenGL wrappers, mimicking opengl syntax */
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h" /* for paint cursor */
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "ED_fileselect.h"
|
||||
#include "ED_screen.h"
|
||||
@@ -875,35 +876,88 @@ void WM_OT_lasso_gesture(wmOperatorType *ot)
|
||||
|
||||
/* *********************** radial control ****************** */
|
||||
|
||||
const int WM_RADIAL_CONTROL_DISPLAY_SIZE = 200;
|
||||
|
||||
typedef struct wmRadialControl {
|
||||
float radius;
|
||||
int mode;
|
||||
float initial_value, value, max_value;
|
||||
int initial_mouse[2];
|
||||
void *cursor;
|
||||
// XXX: texture data
|
||||
GLuint tex;
|
||||
} wmRadialControl;
|
||||
|
||||
static void wm_radial_control_paint(bContext *C, int x, int y, void *customdata)
|
||||
{
|
||||
wmRadialControl *p = (wmRadialControl*)customdata;
|
||||
wmRadialControl *rc = (wmRadialControl*)customdata;
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
float r1, r2, r3, angle;
|
||||
|
||||
/* Keep cursor in the original place */
|
||||
x = p->initial_mouse[0] - ar->winrct.xmin;
|
||||
y = p->initial_mouse[1] - ar->winrct.ymin;
|
||||
x = rc->initial_mouse[0] - ar->winrct.xmin;
|
||||
y = rc->initial_mouse[1] - ar->winrct.ymin;
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glTranslatef((float)x, (float)y, 0.0f);
|
||||
|
||||
|
||||
if(rc->mode == WM_RADIALCONTROL_SIZE) {
|
||||
r1= rc->value;
|
||||
r2= rc->initial_value;
|
||||
r3= r1;
|
||||
} else if(rc->mode == WM_RADIALCONTROL_STRENGTH) {
|
||||
r1= (1 - rc->value) * WM_RADIAL_CONTROL_DISPLAY_SIZE;
|
||||
r2= WM_RADIAL_CONTROL_DISPLAY_SIZE;
|
||||
r3= WM_RADIAL_CONTROL_DISPLAY_SIZE;
|
||||
} else if(rc->mode == WM_RADIALCONTROL_ANGLE) {
|
||||
r1= r2= WM_RADIAL_CONTROL_DISPLAY_SIZE;
|
||||
r3= WM_RADIAL_CONTROL_DISPLAY_SIZE;
|
||||
angle = rc->value;
|
||||
}
|
||||
|
||||
glColor4ub(255, 255, 255, 128);
|
||||
glEnable( GL_LINE_SMOOTH );
|
||||
glEnable(GL_BLEND);
|
||||
glutil_draw_lined_arc(0.0, M_PI*2.0, p->radius, 40);
|
||||
|
||||
if(rc->mode == WM_RADIALCONTROL_ANGLE)
|
||||
fdrawline(0, 0, WM_RADIAL_CONTROL_DISPLAY_SIZE, 0);
|
||||
|
||||
if(rc->tex) {
|
||||
const float str = rc->mode == WM_RADIALCONTROL_STRENGTH ? (rc->value + 0.5) : 1;
|
||||
|
||||
glRotatef(angle, 0, 0, 1);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, rc->tex);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(0,0,0, str);
|
||||
glTexCoord2f(0,0);
|
||||
glVertex2f(-r3, -r3);
|
||||
glTexCoord2f(1,0);
|
||||
glVertex2f(r3, -r3);
|
||||
glTexCoord2f(1,1);
|
||||
glVertex2f(r3, r3);
|
||||
glTexCoord2f(0,1);
|
||||
glVertex2f(-r3, r3);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glColor4ub(255, 255, 255, 128);
|
||||
if(rc->mode == WM_RADIALCONTROL_ANGLE)
|
||||
fdrawline(0, 0, WM_RADIAL_CONTROL_DISPLAY_SIZE, 0);
|
||||
glutil_draw_lined_arc(0.0, M_PI*2.0, r1, 40);
|
||||
glutil_draw_lined_arc(0.0, M_PI*2.0, r2, 40);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable( GL_LINE_SMOOTH );
|
||||
|
||||
glTranslatef((float)-x, (float)-y, 0.0f);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
static int wm_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
int WM_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
wmRadialControl *rc = (wmRadialControl*)op->customdata;
|
||||
int mode, initial_mouse[2], delta[2];
|
||||
@@ -923,13 +977,16 @@ static int wm_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
if(mode == WM_RADIALCONTROL_SIZE)
|
||||
new_value = dist;
|
||||
else if(mode == WM_RADIALCONTROL_STRENGTH) {
|
||||
float fin = (200.0f - dist) * 0.5f;
|
||||
new_value = fin>=0 ? fin : 0;
|
||||
new_value = 1 - dist / WM_RADIAL_CONTROL_DISPLAY_SIZE;
|
||||
} else if(mode == WM_RADIALCONTROL_ANGLE)
|
||||
new_value = ((int)(atan2(delta[1], delta[0]) * (180.0 / M_PI)) + 180);
|
||||
|
||||
if(event->ctrl)
|
||||
new_value = ((int)new_value + 5) / 10*10;
|
||||
if(event->ctrl) {
|
||||
if(mode == WM_RADIALCONTROL_STRENGTH)
|
||||
new_value = ((int)(new_value * 100) / 10*10) / 100.0f;
|
||||
else
|
||||
new_value = ((int)new_value + 5) / 10*10;
|
||||
}
|
||||
|
||||
break;
|
||||
case ESCKEY:
|
||||
@@ -943,8 +1000,14 @@ static int wm_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clamp */
|
||||
if(new_value > rc->max_value)
|
||||
new_value = rc->max_value;
|
||||
else if(new_value < 0)
|
||||
new_value = 0;
|
||||
|
||||
/* Update paint data */
|
||||
rc->radius = new_value;
|
||||
rc->value = new_value;
|
||||
|
||||
RNA_float_set(op->ptr, "new_value", new_value);
|
||||
|
||||
@@ -958,6 +1021,7 @@ static int wm_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Expects the operator customdata to be an ImBuf (or NULL) */
|
||||
int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
wmRadialControl *rc = MEM_callocN(sizeof(wmRadialControl), "radial control");
|
||||
@@ -965,19 +1029,37 @@ int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
float initial_value = RNA_float_get(op->ptr, "initial_value");
|
||||
int mouse[2] = {event->x, event->y};
|
||||
|
||||
if(mode == WM_RADIALCONTROL_SIZE)
|
||||
if(mode == WM_RADIALCONTROL_SIZE) {
|
||||
rc->max_value = 200;
|
||||
mouse[0]-= initial_value;
|
||||
else if(mode == WM_RADIALCONTROL_STRENGTH)
|
||||
mouse[0]-= 200 - 2*initial_value;
|
||||
}
|
||||
else if(mode == WM_RADIALCONTROL_STRENGTH) {
|
||||
rc->max_value = 1;
|
||||
mouse[0]-= WM_RADIAL_CONTROL_DISPLAY_SIZE * (1 - initial_value);
|
||||
}
|
||||
else if(mode == WM_RADIALCONTROL_ANGLE) {
|
||||
mouse[0]-= 200 * cos(initial_value * M_PI / 180.0);
|
||||
mouse[1]-= 200 * sin(initial_value * M_PI / 180.0);
|
||||
rc->max_value = 360;
|
||||
mouse[0]-= WM_RADIAL_CONTROL_DISPLAY_SIZE * cos(initial_value);
|
||||
mouse[1]-= WM_RADIAL_CONTROL_DISPLAY_SIZE * sin(initial_value);
|
||||
initial_value *= 180.0f/M_PI;
|
||||
}
|
||||
|
||||
if(op->customdata) {
|
||||
ImBuf *im = (ImBuf*)op->customdata;
|
||||
/* Build GL texture */
|
||||
glGenTextures(1, &rc->tex);
|
||||
glBindTexture(GL_TEXTURE_2D, rc->tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, im->x, im->y, 0, GL_ALPHA, GL_FLOAT, im->rect_float);
|
||||
MEM_freeN(im->rect_float);
|
||||
MEM_freeN(im);
|
||||
}
|
||||
|
||||
RNA_int_set_array(op->ptr, "initial_mouse", mouse);
|
||||
RNA_float_set(op->ptr, "new_value", initial_value);
|
||||
|
||||
op->customdata = rc;
|
||||
rc->mode = mode;
|
||||
rc->initial_value = initial_value;
|
||||
rc->initial_mouse[0] = mouse[0];
|
||||
rc->initial_mouse[1] = mouse[1];
|
||||
rc->cursor = WM_paint_cursor_activate(CTX_wm_manager(C), op->type->poll,
|
||||
@@ -986,7 +1068,7 @@ int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
/* add modal handler */
|
||||
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
|
||||
|
||||
wm_radial_control_modal(C, op, event);
|
||||
WM_radial_control_modal(C, op, event);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
@@ -1001,8 +1083,6 @@ void WM_OT_radial_control_partial(wmOperatorType *ot)
|
||||
{WM_RADIALCONTROL_ANGLE, "ANGLE", "Angle", ""},
|
||||
{0, NULL, NULL, NULL}};
|
||||
|
||||
ot->modal= wm_radial_control_modal;
|
||||
|
||||
/* Should be set in custom invoke() */
|
||||
RNA_def_float(ot->srna, "initial_value", 0, 0, FLT_MAX, "Initial Value", "", 0, FLT_MAX);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user